2008年12月アーカイブ

CSSでテンプレート(段組レイアウト)を作成する場合、ボックスモデルの理解はかかせません。

段組レイアウトでは、段組を例えばdiv要素などのブロックレベル要素で枠を作ります。ボックスは以下の4つの領域から成ります。

  1. コンテンツ(内容)ボックス
  2. パディングボックス
  3. ボーダーボックス
  4. マージンボックス

1.コンテンツ(内容)ボックス

テキストや画像などの領域です。widthとheightで領域を指定します。

2.パディングボックス

線の領域より内側の余白です。paddingで領域を指定します。

3.ボーダーボックス

線の領域です。borderで色、太さ、線の種類を指定できます。

4.マージンボックス

線の領域より外側の余白です。marginで領域を指定します。

注意すべき点は、隣接するブロック間の縦方向のマージンは「相殺する」ということです。

例えば、AとBというボックスがあって、Aのマージンが30px、Bのマージンが50pxの場合は、その間の余白(マージン)は50pxになります。両方が正のマージンの場合、その大きい方のマージンが指定されます。

Aのマージンが-30px、Bのマージンが50pxの場合は、その間の余白(マージン)は20pxになります。片方が負のマージンの場合、両方のマージンを足した値が適用されます。

Aのマージンが-30px、Bのマージンが-50pxの場合は、その間の余白(マージン)は-50pxになります。両方が負のマージンの場合、その小さい方のマージンが指定されます。

マージンの相殺については仕様書を参考にしてみてください。

モードの違い

比較的新しいブラウザは、DOCTYPE 宣言によって「標準準拠モード」「ほぼ標準準拠モード」「後方互換モード」というレンダリングが変わる機能がついています。

「ほぼ標準準拠モード(Almost Standards Mode)」というのは、"ほぼ"標準準拠ですがテーブルセル内の画像のレイアウトが後方互換の拡大解釈を行うというものです。

「標準準拠モード」と「ほぼ標準準拠モード」では、widthおよびheightはボックスの大きさはコンテンツ(内容)ボックスの大きさになります。

標準準拠モード

しかし、「後方互換モード」では、コンテンツ(内容)ボックス領域の幅の中に、パディングボックス領域およびボーダーボックス領域が含まれてしまいます。つまり、widthの中にpaddingとborderの大きさが含まれてしまいます。

後方互換モード

「標準準拠モード」になるDOCTYPE 宣言には以下のようなものがあります。ただしブラウザによっては「ほぼ標準準拠モード」にもなる場合があります。

XHTML1.0 Strict
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
XHTML1.0 Transitional
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
HTML4.01 Strict
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
HTML4.01 Transitional
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

DOCTYPE 宣言はあくまで、レンタリングを変えるのが目的ではなくHTMLのバージョンを示すことだと言うことは忘れないでください。

また、XML 宣言の有無にもよって、モードが切り替わる場合があります。

IE6ではDOCTYPE 宣言の前に何か書かれていると「後方互換モード」になるという仕様があって、XML 宣言を記述してしまうと仕様のとおり後方互換モードになってしまいます。

もし、後方互換モードにしたくない場合は、

  1. XML宣言を記述しない。XHTMLの場合は文字コードがUTF-8あるいはUTF-16であれば、XML宣言を省略することができます。
  2. XHTMLではなくHTMLで記述する。

などの方法があります。

ちなみに私は、基本的にXML宣言あるなしに関わらず極力「標準準拠モード」でも「後方互換モード」でも同じレイアウトになるようにコーディングしています。

ポイントは「ひとつのボックスに対してwidthと一緒にpaddingやborderを指定しない」と言うことです。widthしか指定しないdivボックスを作成し、その中のdivタグやpタグなどにpaddingやborderを指定するようにしています。

liタグでメニューを横並びにする方法は主に2つあります。

1.floatプロパティを使う

横並びをするには、floatプロパティを用いる方法が一般的です。ただし、いろいろと問題があります。

まず、リストタグの次にコンテンツがある場合、そのコンテンツはリストの横に回りこまれてしまうので、回り込みを解除しなければなりません。

また、floatプロパティを使うと親要素(ここではulタグ)の内容が0になってしまい、例えば、ulタグに背景やborderを適用しようとしてもうまく表示できない場合があります。この解決方法として、「clearfix」というコードの書き方があります。

あと、注意しなければならないのが、リストマークです。この方法ではIEではリストマークが消えているように見えるのですが、Firefoxなどの他のブラウザではきちんとリストマークが見えてしまっています。リストマークを表示したくない場合は「list-style:none;」を指定しましょう。

以上をふまえてコードは以下のようになります。

(X)HTMLコード

<ul class="menu">
<li><a href="#">MENU1</a></li>
<li><a href="#">MENU2</a></li>
<li><a href="#">MENU3</a></li>
<li><a href="#">MENU4</a></li>
<li><a href="#">MENU5</a></li>
</ul>

CSSコード

ul.menu {
   margin:0;
   padding:0;
}

ul.menu li {
   float:left;
   list-style:none;
}

/* モダンブラウザ(Firefox Opera Safari)対策 */
ul.menu:after{
   content:".";
   display:block;
   height:0;
   clear:both;
   visibility:hidden;
   font-size:0;
}

/* Win版IE7とMac版IE5対策 */
ul.menu{
   display:inline-block;
}

/* Win版IE5および6対策 */
/* Hides from IE-mac \*/
* html ul.menu{
   height:1px;
}

ul.menu{
   display:block;
}
/* End hide from IE-mac */

2.inline要素を使う

本来のリストが縦並びになるのは、ブラウザのデフォルトCSSにより、liタグのdisplayプロパティが「block要素」になっているためです。よって、displayプロパティを「inline要素」にすれば横並びになります。

しかし、注意しなければならないことがあります。

ブラウザによっては、なぜかulタグの上下やliタグの間に謎の隙間が空いてしまう場合があります。これはコードの書き方によるのですが、改行を半角スペースに変換してしまうようです。

この解決方法としては、コードを1行で書いてしまうか、改行の際に「<!--(改行)-->」というふうに書くかの2つがあります。

以上をふまえて、ソースコードは以下のようになります。

(X)HTMLコード

<ul class="menu"><!--
--><li><a href="#">MENU1</a></li><!--
--><li><a href="#">MENU2</a></li><!--
--><li><a href="#">MENU3</a></li><!--
--><li><a href="#">MENU4</a></li><!--
--><li><a href="#">MENU5</a></li><!--
--></ul>

CSSコード

ul.menu {
   margin:0;
   padding:0;
}

ul.menu li {
   display: inline;
}