P-0021 CSS のテクニック・デザイン編 - CSS ならではの高度なレイアウト -

はじめに

CSS を使うと複雑なレイアウトでも簡単に実現できますが、考え方に多少「コツ」が必要です。ここでは「デザイン」の観点から、 CSS の利用方法について解説を加えようと思います。

尚、以下の文書はある程度 HTML やスタイルシートの知識がある人……少なくとも HTML ソースを直書きできる人を対象にしていますので、悪しからず。

あらかじめ言っておきますが、 CSS は万能ではありません。 CSS を使うと高度なレイアウトを実現できますが、当然できないこともあります。文字の回転・角度の変更はその代表で、こういった表現は今のところ、画像を使わないと実現できません。また、絶対にしてはいけないこともあります。

勘違いされがち(?)ですが、 CSS を使いさえすれば格好いいデザインができるというわけでもありません。 CSS はあくまでレイアウトを実現するための道具の一つに過ぎず、それをどう使うかは結局の所、制作者の腕前次第なのです。

道具には当然、向き不向きがあります。 CSS に適した使い方でこそ CSS は真価を発揮するのですが、「適した使い方」を身につけるには経験が必要です。 CSS についての解説は他のサイトを参考にしていただくことにして、ここでは、「基本的な使い方」を組み合わせて高度なレイアウトに発展させるための足がかりとなる考え方(の一部)を紹介しようと思います。

HTML 側のテクニック

class 属性・ id 属性の利用

CSS の指定は全て、 HTML の要素(タグで囲まれた部分)に対して行います。

  • <h1></h1>で囲まれた部分を大きな文字にする
  • <strong></strong>で囲まれた部分を太字にする

CSS の「スタイルの適用対象」は「セレクタ( selector )」と呼ばれ、多くの場合 HTML の要素そのものをセレクタとして扱います

しかし HTML に用意されている要素は「大見出し」「リスト」といったおおざっぱなものしかなく、「ギャラリーの見出し」や「目次のリスト」といった細かい分類まではされていません。そこで出てくるのが、それぞれの要素の分類を示す属性「 class 」と、要素の固有の名前を示す属性「 id 」です。

class と id は HTML をより高度に利用するためのものですが、 CSS では、こうして拡張した「それぞれの要素」をセレクタにして「日記の日付」や「曲目のリスト」といった細かい分類でスタイルを指定することができますこれは言い直せば、 class や id を使うとより細かい指定ができるということになります。

  • <h2 class="index" ></h2>の部分を大きな文字にする
  • <h2 class="DocContent" ></h2>の部分を下線付きにする
  • <h2 class="sub content" ></h2>の部分を小さめの文字にする

同じ「 h2 」要素でも、 class の値でそれぞれを区別できる。

class 名の付け方の注意点

class 名には「分類」「意味」を連想できる名前を使いましょう。例えば「注目!」という字句をここだけ赤の文字で表示させたい場合以下のように書いてしまいがちですが、これはアウトです。

全員<strong  class="red" >注目!</strong>
   strong .red  {color:red;} 

「注目!」という字句を青で表示したくなったときを考えてみましょう。

strong .red  {color: blue ;} 

「 red (赤)という class 名なのに、表示される色は blue (青)」。これはどう考えても矛盾してます。それだけでなく、色と名前が食い違っているために、ソースが極端にわかりにくくなってしまいます

ここでは「『強調』の中でも、注目させる場所」という分類で class を指定しているのですから、 class 名にも「注目・注意」という意味の語をあてておくのがベストでしょう。

全員<strong  class="attention" >注目!</strong>

こうすれば、後で色を変えたくなったときでも矛盾しませんし、何よりソースを眺めたときに意味が分かりやすいです。

尚、 class と id は CSS における役割は同じですが、意味は全く別のものです。混同しないように気をつけてください

グループ化

前述の通り、 CSS では HTML 文書中のマーク付けを「目印(セレクタ)」にしてスタイルを指定します。よって、基本的に何もマーク付けされていない部分にはスタイルを指定できません

本文中のひとまとまりの部分に border を指定したいというような場合、 div 要素などによるグループ化を使います。 div 要素・ span 要素はそれ自体は意味を持っておらず、囲った部分がひとまとまりの部分であるということだけを示します。これを利用し、 class 属性や id 属性と組み合わせて CSS のセレクタにすれば、「前文と本文、本文とコンテンツリストで背景を変える」というような凝った指定が可能となります。

<h2>スタイル</h2>
<div class="introduction">←「導入部」というグループ
  <h3>はじめに</h3>
  <p>HTML ・ XML 用のスタイル言語には、
      現在3種類が存在します。</p>
  <ul>
     <li>CSS<li>JSSS<li>XSL
  </ul>
</div>
  <h3>CSS</h3>
  <p>W3C の推奨している「 CSS 」は、 ...

ブロック要素をグループ化する場合はブロック要素の「 div 」を、インライン要素をグループ化する場合はインライン要素の「 span 」を使います。

グループ化とは、 CSS から見れば「ボックスを作り出す」テクニックとも言えます。その気になれば画面の好きな位置に好きな数だけボックスを表示させることもできます……が、 HTML 的には無意味な(レイアウト目的だけの)要素を記述するのは望ましくないので、使いすぎないようくれぐれも注意しましょう。

CSS 側のテクニック

ボックスの利用

ボックス系プロパティの border ・ margin ・ padding は、上下左右それぞれの値を別個に指定できます

p { border-width: 0 0 2px 10px;
    padding: 0 0 5px 1em; } 
※上と右は太さ「0」、左は 10pixel 、下は 2pixel の border を表示。また、 border と内容(テキスト)の間には、左に1文字分・下に 5pixel の余白をとる。

特に border は色・太さ・線の形状のすべてが上下左右別々に指定できるので、上手く使えば、今まで画像や table を使わなければできなかったような表現もできます。

また、 CSS 2 ではボックスに対し「幅( width )」と「高さ( height )」も指定できます。

CSS でのレイアウトは、この「ボックス」をどう利用するかにかかっています。後述のテクニックもすべてボックスが基本になります。とはいえこれだけだと矩形が主体のデザインにならざるを得ませんので、後述の背景との組み合わせを活用するのも重要でしょう。

ポジショニング

ポジショニング( Positioning )とは各々の要素(セレクタ)を自由に配置するための仕組みで、 position プロパティで配置のタイプ(相対/絶対指定)を、 top/bottom/left/right で上下左右のオフセット値を指定します。

h1.title
   { position: absolute; /* 絶対指定配置 */
    top: 50px; left: 10%; /* 上から 50pixel 、左から10%の位置 */ } 

従来の table やスペーサーを使った配置はオーサリングツールの手を借りないと実現できないほどややこしいものですが、 CSS のポジショニングはもっと直感的に、ページ中の各要素を切り張りするような感覚でページ上に配置できるのが大きな特徴です。

position で主に使うのは「 relative (相対指定──指定したオフセット値の分だけ本来の位置からズレて表示される)」と「 absolute (絶対指定──本来の配置を無視してウィンドウ内端からの位置を指定する)」です(シートが複雑になってくると「 static (ポジショニング無効)」も使うことがあるかもしれません)。「 fixed (固定── absolute と似ているが、スクロールしてもウィンドウ内で場所が変わらない(常に表示され続ける))」は対応ブラウザがまだないので、使わない方がいいです。

オフセット値にパーセント値を指定すると、ウィンドウサイズに合わせて要素が移動します。ウィンドウサイズが変わっても相対的な位置関係を維持できますので、うまく使えば「放物線状の配置」も可能です。

<ul>
  <li id="welcome">Welcome 
  <li id="gallery">Gallery
  <li id="dialy">Dialy
  <li id="profile">Profile
  <li id="links">Links
</ul>
   li {position:relative;}
   li#welcome { left: 32%; }
   li#gallery { left: 16%; }
   li#dialy   { left: 8%; }
   li#profile { left: 4%; }
   li#links   { left: 2%; } 
  • Welcome
  • Gallery
  • Dialy
  • Profile
  • Links

なお、このような使い方をする場合、要素の区別には class より id を使う方がいいでしょう。

position:fixed

fixed 指定は今のところ Netscape 6 ( Mozilla )と Mac 版 InternetExplorer 5.0 が対応していますが、 WinIE 5 は fixed を指定すると配置が崩れるなどのバグがあるので、なるべく使わないのが無難でしょう。使う場合は、 WinIE でスタイルを適用しないようにするテクニックと組み合わせるのがベターです。

なお、 fixed 指定を使う場合には、要素の縦の長さにも注意する必要があります。縦に長い要素を fixed で表示すると下の方がどう頑張っても読めないということが起こり得ます。もし使うなら、 overflow:scroll などと組み合わせる必要があるでしょう。

背景との組み合わせ

CSS を使うと背景画像の表示位置や繰り返しについても細かく制御できます。

背景画像の繰り返しを「無し」にすると、事実上画像を好きなところに配置できるとの同じ効果が得られます。

<div class="chapter">
  <h4>例 -example</h4>
  <p>&lt;div class="chapter"&gt; に対し、背景画像を繰り返し無し、
         左から100%(右端)・上から0の位置(上端)に表示する。</p>
</div>
   div.chapter {background:url(bg.gif) no-repeat 100% 0;}
                 /* 画像には透過 GIF などを使用することもできる */
   h4 { border-bottom-width: 1px;
         font-size: larger; font-weight: normal; }
例 -example
<div class="chapter">に対し、背景画像を繰り返し無し、左から100%(右端)・上から0の位置(上端)に表示する。

これを応用すると、「画像を使ったメニュー」に似た効果も得られます(当サイトのメインコンテンツのコンテンツリストもその例です)。上手くやれば、クリッカブルマップを使うのと同じようなメニューも作れます。

背景には透過画像も使えます。背景色と馴染むようにグラデーションさせるのも効果的でしょう。このテクニックをベースにさまざまなアイデアを組み合わせることで、表現の幅は大きく広がります。

尚、 W3C の内部組織の WAI では、クリッカブルマップのメニューを使う場合、同じ内容のテキストリンク(クリッカブルマップに非対応のブラウザのための配慮)も併記しておくことを推奨していますが、この手法ならテキストリンクだけでクリッカブルマップと同じことができ、二度手間を省くことができます。

けっこう知られていませんが、 background に fixed を指定(背景を固定)すると、画像の大小に関わらずページのスクロールが極端に遅くなります。閲覧者のことを考えた場合、 fixed 指定はなるべく避けるのが良いようです(といいつつこのページでも使ってたりしますが)。

display プロパティの利用

HTML の要素には大別してブロック要素・インライン要素の二種類があり、ブロック要素はその前後で改行されるようになっていますが、 display プロパティを使えば、<a>の前後で改行させたり<ul>の前後で改行させなかったりのように、表示上の規則を自由に変更することができます。

display の代表的な利用法として、 border の表示制御があります。 CSS は仕様上、インライン要素のセレクタにも border を指定できることになっていますが、 IE 5.0 以前はインライン要素への border 指定をサポートしていません。そこで display プロパティでブロック系表示に指定しなおしてやることで、インライン要素にも border を表示できるようになるというわけです。

インライン要素へのブロック要素的な表示指定は、見出しのサブタイトルのレイアウトにも利用できます。サブタイトル部分を span などでマーク付けして display: block; を指定することで、派手なレイアウトに発展させることができます。

h4 .subtitle {
    display: block;
    font-size: medium;
    margin-left: 10%; padding-left: 5%;
    border-top: thin solid;
    }
<h4>Example
   <span class="subtitle">display プロパティの利用例</span></h4>
Example display プロパティの利用例

IE 5.5 以降と Netscape 6 は、インライン要素への border 指定にも対応しています。

また、リストの表示を変えるのにも利用できます。リスト項目( li 要素)はブロック系なので項目は縦に並ぶのが標準ですが、 li 要素をインライン系表示に変更すると、項目が横に並ぶようにできます。

display: block; のままのリスト

  • 項目 1,
  • 項目 2,
  • 項目 3

display: inline; を指定したリスト

li { display: inline; } 
  • 項目 1,
  • 項目 2,
  • 項目 3

display の利用は、複雑なレイアウトを作るには不可欠です。また、 display:none とすれば要素を非表示にすることもできます。

フロート

フロートとは、早い話「流し込み」処理のことです(テキストを流し込む際に、テキストとは別に存在し、テキストが重ならない要素のことを「フロート」といいます)。

新聞記事などで、テキストが画像をよけるように配置されていることがありますが、 CSS でも「 float 」プロパティで同じことができます。

 float: left ; 

float プロパティはフロートにしたい要素に指定します。「 left 」で左側に(サンプル画像と同じように)、「 right 」で右側に配置できます。なお、「 center 」はありません

ちなみに、 float は画像だけでなく、テキストや表など全ての要素に指定できますので、引用記事をフロート表示するといった使い方もできます。

フロートを応用すると、タイトルの装飾(当サイトのメインコンテンツのページタイトルもその例です)や簡単な段組も表現できます。

span.first-letter { float: left; font-size: 2em; color: aqua; } 

語の教科書やなんかでよく見かけるスタイルですね。 CSS 2 の :first-letter 疑似要素を使うのがベターですが、今のところ MacIE 5 と Mozilla(Netscape 6) しか対応していないのが残念。ここでは span でマーク付けしています。

ul#lower { float: left; /* 下半期分を左寄せ */
             margin: 0em 1em; width: 8em; } 
  • 2000/12
  • 2000/11
  • 2000/10
  • 2000/9
  • 2000/8
  • 2000/7
  • 2000/6
  • 2000/5
  • 2000/4
  • 2000/3
  • 2000/2
  • 2000/1

組み合わせ

要素の重ね合わせ

ポジショニングを使うと、要素同士を重ね合わせることもできます( z-index プロパティで重ね合わせの順序も変えられる)。マイナスのマージンでも似たようなことができますが、要素の配置を変える目的の場合は、ポジショニングを使いましょう。

<h1>
<span class="main">black</span>
<span class="sub">white</span>
</h1>
   .main,.sub{ display: block; padding: 1em; position: relative;
                width: 50%; height: 3em; text-align: center; }
   .main { color: white; background: black; }
   .sub  { color: black; background: white;
              top: -0.8em; left: 20%; } 

black white

z-index を使う場合、数値は絶対的な「階層の深さ( z 値)」を表すものではないという点に注意しましょう。無指定の状態が「0」で、 z-index:2 で「2階層上」、 z-index:-1 で「1階層下」となります。 z-index は扱いが難しいので、慣れないうちは触らないのが無難です。

背景の重ね合わせ

CSS では各セレクタには背景を一種類しか指定できませんが、要素をいくつも重ねることで、複数の背景画像を重ね合わせることができます。感覚としては、 Photoshop などのレイヤに似た考え方と言えるでしょう。

例えば4枚の背景を重ねれば、テキストの四隅に画像を表示するようなことも可能です。背景色との組み合わせで「丸角テーブル」を再現することもできます。

<div class="l1"><div class="l2"><div class="l3"><div class="l4">
   <h4>疑似レイヤ</h4>
   <p>
    この手法は、 Photoshop などのレタッチツールに搭載されている
    「レイヤ機能」に似ています。
    IE のビジュアルフィルターや CSS 3(?) の Opacity で
    各「レイヤ」の透明度を調整すば、更に面白い効果が出せるでしょう。
   </p>
</div></div></div></div>
   .l1, .l2, .l3, .l4 { margin: 0; padding: 0; }
   .l1 { background: url(bg_tl.gif) no-repeat 0 0; }
   .l2 { background: url(bg_tr.gif) no-repeat 100% 0; }
   .l3 { background: url(bg_bl.gif) no-repeat 0 100%; }
   .l4 { background: url(bg_br.gif) no-repeat 100% 100%;
         padding: 10px; } 
疑似レイヤ
この手法は、 Photoshop などのレタッチツールに搭載されている「レイヤ機能」に似ています。 IE のビジュアルフィルターや CSS 3(?) の Opacity で各「レイヤ」の透明度を調整すば、更に面白い効果が出せるでしょう。

ただ、このような使い方──「レイアウトのためのマーク付け」を施すようなことは HTML や XML の思想的には望ましくないので、可能な限り避けるべきでしょう。使うとすれば、「偶然にもいくつかの要素が入れ子になっている」ような場合に「その状況を利用する」、という程度がベターだと思います。

当サイトのメインコンテンツなどでも、この効果をいくつか利用しています。

CSS のセレクタだけでページを判別する

CSS にはページ判別の仕組みがないため、例えばトップページと日記のページでスタイルを変えたいときは別々のシートを用意して link 要素で使い分けるという感じになりますが、 CSS の id セレクタや class セレクタを利用すれば、単一のスタイルシートでもページごとに表示を変えられます

id の指定例

  • トップページ:<body id="cover">
  • 日記のページ:<body id="diary">

class の指定例

  • メインコンテンツ:<body class="main">
  • サブコンテンツ:<body class="sub">

CSS での利用例

h1 { font-size: large; }
 #cover  h1 { font-size: xx-large; }
  /* トップページの見出しだけ文字を大きくする */
body { font-size: medium; }
body .main  { background-image: url(main.jpg); }
body .sub  { background-image: url(sub.jpg); }
  /* 全ページ共通の指定とコンテンツのレベルごとの指定を
     分けて記述する */

共通のスタイルとページごとのスタイルを別々のファイルにして適宜組み合わせることをモジュール化といいますが、あまりシートを細かく分けすぎると管理が煩雑になったりページの表示が遅くなったりします。ページごとのスタイルの違いがあまりないのなら、こちらの方法を使った方がいいでしょう。

見出し画像を背景にする

背景の繰り返し制御と配置位置を駆使すれば、背景画像を見出し代わりに使うこともできます。ページごとの見出しにはあまり有効ではありませんが、サイトのタイトルをトップページに表示する場合には効果的でしょう。

具体的には、タイトルの表示を消して、背景に「タイトル文字列を入れた画像」を配置します。こうすることで、スタイルシート対応環境では装飾済のタイトルを、非対応環境では普通の文字だけのタイトルを表示できます。

#cover h1 { visibility: hidden; font-size: 1px; }
  /* display: none; を使うとアンカーが使えなくなるので、
     visibility: hidden; で見た目だけ消す */
#cover {
  background: url(title.gif) no-repeat;
  padding-top: 80px;
  }
  /* 画像内のタイトル文字列が本文に重ならないよう、
     padding を設定しておく */
<body id="cover">
   <h1>タイトル</h1>
    ...

当サイトでも Purple スタイルのトップページにこのテクニックを応用していて、 h1 要素の width と height を画像と同じサイズに合わせ、 h1 の文字列("outsider reflex"の部分)自体は font-size を小さくし目立たなくさせています。また、 Flat スタイルでは全ページの body にタイトルを含む背景画像を表示しています。

最後に

概念の転換

従来の「ここを大きな文字で、ここを四角で囲って」という「絵を描く」ような直接的な考え方に囚われていては、 CSS は使えません。もっとコンピュータ的・大局的な考え方が必要となります。

これまでの一般的な「紙の上でのレイアウト」と何が違うのか、わかるでしょうか。 CSS を使ったページ作成を料理に例えてみましょう。

材料を切るとき、(完成した後のことを考えて材料にカッティングを施したりする技法もありますが)大概は調理段階では最後の段階の見栄えは全く考えず、盛りつけの段階になって初めて「見栄え」を考えると思います。色が良いからなどの理由で素材をコーディネイトするのではなく、あくまで栄養のバランスを考えて調理し、そういう「絶対に必要な部分」を終えてから、改めてどうでもいい「レイアウト」に着手する──少なくともうちの母はこういう考え方で料理を作っています。

CSS を使う場合、適用対象となる HTML 文書の記述の段階では、レイアウトについて考慮する必要は全くありません。というか、考慮してはいけません。とにかくあるがままに文書を打ち込んでいき、その純粋な文書データに「強調」「引用」などのマーク付けを行って、単に「そこがどういう意味であるか」だけを記述するのが HTML 。そして CSS で「こういう意味を持った要素はこういう表示にする」とだけ記述する。これが「 CSS 的な」レイアウト法です。だから、そこに「意味」がなければ、ページ中にただ単にボックスを表示させたりただ単に色を付けたりということは不可能なのです。

スタイルシートは HTML という文書の意味を記述するものレイアウト面を担当する補助的存在である、ということをまずは理解してください。「ページを CSS でデザインする」のではなく「 HTML 文書を CSS で装飾する」という考え方でないと、 CSS は扱いづらいだけのただの役立たずになってしまうのです。

ページの一部分だけに注目してすぐに「ここをこう表示したい」と考えるのではなく、もう少し落ち着いて、全てのページ内にある「これこれこういう構成要素」という共通の部品を見つけだし、その部品をどう表示するかを考える──このように一歩引いて見直してみるのが CSS の基本です。この概念の転換ができれば、 CSS は一気に「理解り易い、簡単なもの」となります。最初にこの思考の転換を行うのが、 CSS を理解して使いこなす最大の近道と言えます。

チャレンジが大切

CSS の最大の利点は、「手軽に全ページのレイアウトを変更できる」というところでしょう。デザイン変更の度に全てのページを書き直さなければならない従来の手法と違いずっと身軽ですから、常に実験し続けることができます。

CSS に用意された各プロパティは単純なものばかりですが、組み合わせ次第では高度なデザインを作り出せます。 CSS の世界は、 REGO のように単純でいて奥が深いと言えます。皆さんもトライ & エラーでちょくちょく実験を繰り返して、面白いプロパティの組み合わせ方を探してみましょう。

おまけ

私もいくつかシートを作ってみました。 JavaScript でシートを切り替えられるようにしてみたので、ヒマがありましたら見てやってください。トップページから選択できます。