IE6:widthとpadding/borderのバグ
今さら過ぎるけどIE6におけるwidthとpadding/borderのバグ潰し。
昔は横幅が合わなかったり、親ボックスの幅超えちゃってカラム落ちとかよくあった…
IE6ではぴったりなのにFirefoxなんかで見るとずれてやるじゃネーか、と。
原因はIEのwidthの解釈のバグ。
IE6には表示方法が今までのバグが修正された標準準拠モードと、IE5以下と互換性(今までのバグも含む)がある後方互換モードの2種類ある。
標準準拠モードでなら全く問題ないが、後方互換モードだとwidthの値が間違って解釈されて表示のされ方が変わってくる。
以下、説明。
互換モードではpadding/borderがwidthに含まれる
分かりやすいようにborder、padding、本文に色付けて比較。
XHTML
<div> この岸辺露伴が最も好きな事のひとつは、自分で強いと思ってるやつに「NO」と断ってやる事だ・・・ </div>
css
div { width: 250px; padding: 20px; border: 10px #fff solid; }
標準準拠モードではwidthの値にpaddingとborderの値が加算された合計310pxがボックスの幅になる。
width + padding + border = ボックスの幅
250px + 20px + 40px = 310px
後方互換モードでは、widthの値にpaddingとborderの値が含まれ、ボックスの幅は240pxになる。
なのでwidth(本文の範囲)が250px - 20px - 40px = 190pxと狭くなってしまう。
この違いを知らないと、widthと同じ幅の画像を張った際にはみ出たり、floatでカラム組んだときにカラム落ちなどレイアウトが崩れる。
IE6を標準準拠モードで動かす
これらを回避する方法の1つとしてIE6を標準準拠モードで動作させる方法がある。
必ずソースの一行目にDOCTYPE宣言を書けばIE6は標準準拠モードで動作し、widthを正しく解釈してくれる。
これなら手っ取り早く見た目を同じに出来るが、この方法だと問題がある。
常時後方互換モード状態のIE5.5/IE5では表示が崩れることと、XHTMLを書くとき一行目にxml宣言を書くのでIE6が強制的に後方互換モードになること。
前者は自己満足したい人以外無視できるからスルー。
後者だとIE6は後方互換モードで動作し、その他は標準準拠モードで動作するのでweb標準にあわせて書いても表示が崩れてしまう。
一行目のXML宣言をスルーしてDOCTYPE宣言を書けば両方とも標準準拠モードで動作させることが出来る。が、
web標準に準拠させてxml宣言も書きたい人はどうすればいいのか。
widthとpadding/borderを一緒に指定しない
というわけで回避方法2。
ボックスを2つ用意して、外側のボックスにwidthを、内側のボックスにpadding/borderを指定するやり方。
XHTML
<div class="c1"> <div class="c2"> この岸辺露伴が最も好きな事のひとつは、自分で強いと思ってるやつに「NO」と断ってやる事だ・・・ </div> </div>
css
div.c1 { width: 310px; } div.c2 { padding: 20px; border: 10px #fff solid; }
外側のボックス(div.c1)に全体の幅であるwidth:310pxだけを指定して、paddingとborderは指定しない。
そして内側のボックスにpadding:20pxとborder:10px #fff solidを指定する。
余白の部分をpaddingじゃなくてmarginにすると、marginの相殺が起きたりするのでpaddingの方が無難。
こんな感じにwidthとpadding/borderを一緒に指定しないようにすれば、標準モードでも互換モードでもボックス全体の幅が310px、本文の範囲が250pxと見てくれが同じになる。
しかもxml宣言も書けるし、IE6が後方互換モードになろうがそんなこと気にしなくてもいいという。
cssハックでIE6にだけ別のスタイル当てようとしてる人や、仕方なくxml宣言スルーしてたxhtml使いの人はこの方法マジオススメ。
ここで1つ注意。
上の例では内側のボックス(div.c2)にpaddingとborderを同時に指定しているけれど、実を言うとpaddingとborderの同時に指定はしない方がいい。
何でかって言うと、borderと背景画像を同時に使うときちょっとメンドイ事が起こるから。
どうメンドイかは↓参照。
IE6/7:borderと背景画像
borderを指定するなら背景画像を使うのがオススメ。
div病に注意
ボックスを2つ用意すると書いたけれども、気をつけることがある。
divタグを乱発するdiv病という病だ。
例ではdiv要素をdiv要素で括っているけれども、実際は別の要素を組み合わせたほうがいい。
記事を載せる部分にwidthを指定したdiv要素を使って、内側にpaddingで余白をつけたp要素で本文書いたり。
他には、リストタグのul/ol/dl要素でwidthを指定しli/dt/dd要素でpaddingを指定したり。
他にも色々組み合わせあると思うけど、何でもかんでも組み合わせるんじゃなくその時々の状況で正しい要素を使うようにする必要がある。
menuつくるならdiv要素の中にp票素を使うんじゃなくて、ul要素とli要素組み合わせたりネ。