CSS実験室
inline-blockの奇妙な世界
inline-blockとは、displayプロパティの値のひとつで、表示形式を「インラインに流し込むことのできるブロック要素」にするためのもの。まともに対応しているのが、OperaとSafari、それになぜかMac版IEくらいというマイナーな存在だが、なかなか興味深い振る舞いをする値なので、いろいろと検証してみた。
まず、「インラインに流し込むことのできるブロック要素」とはどういうものなのかを見てみるために、.inlineblockというクラスを作り、div要素に指定してみた。また、「インラインに流し込むことのできるブロック要素」とは、言い換えれば、「幅と高さを指定できるインライン要素」ということだから、span要素にも指定した。
【スタイルシート】
.inlineblock {
display: inline-block;
width: 100px;
height: 30px;
background: #000000;
font-size: 10pt;
line-height: 30px;
text-align: center;
color: #ffffff;
margin-bottom: 1px;
}
【HTML】
<p>div要素にdisplay: inline-blockを指定した場合</p>
<div class="inlineblock">inline-block</div>
<div class="inlineblock">inline-block</div>
<div class="inlineblock">inline-block</div>
<div class="inlineblock">inline-block</div>
<p>span要素にdisplay: inline-blockを指定した場合</p>
<span class="inlineblock">inline-block</span>
<span class="inlineblock">inline-block</span>
<span class="inlineblock">inline-block</span>
<span class="inlineblock">inline-block</span>
これを、inline-blockに対応しているOperaと、対応していないFirefoxで表示させてみようと思うのだが、その前に、IEについて触れておかなければならない。最初に、inline-blockにちゃんと対応しているのは、OperaとSafari、Mac版IEくらいと書いたが、実はIE6.0以降もいちおう対応している。以下、「Internet Explorer 6 におけるCSSの拡張」より引用。
SPAN、B、および I などのインライン 要素は、width や height プロパティをサポートしません。標準準拠モードを有効にして、インライン 要素の width や height プロパティを設定するには、インライン 要素の display プロパティを inline-block に設定します。
要するに、ブロック要素をインライン要素的に扱うことはできないが、インライン要素をブロック要素的に扱うことはできる、ということである。これを踏まえ、Opera(9.21)、Firefox(2.0)、そしてIE(6.0)の3種類のブラウザで検証してみることにする。
●Operaの場合
inline-block完全対応のOperaでは、div要素がインライン要素的に横に並び、span要素がブロック要素的に幅と高さを持つ。結果、両方とも見た目的には同じになる。
●Firefoxの場合
inline-blockに対応していないFirefoxでは、div要素はブロック要素のまま、縦に積み重なり、span要素はインライン要素のまま、指定した幅・高さは無効になっている。
●IEの場合
変則的なのがこのIE。div要素にinline-blockを指定してもブロック要素のままだが、span要素にinline-blockを指定した場合は、ブロック要素的に幅と高さの指定が有効になる。
さて、ここまでは、まあ、はっきりいってどうでもいいことである。しょせん、Firefoxなどではiline-blockは使えないのだから。そもそも、なぜinline-blockに着目したかというと、いわゆるclearfixでIE7 & MacIE対策用にinline-blockが使われているからだ。しかし、floatのクリアにinline-blockが有効なのはIE7とMacIEだけではない。もともとinline-blockに完全対応しているOpera、Safariはもちろん、IE6でも、inline-blockでfloatをクリアできる。このことを次のソースを使って確認してみよう。
【スタイルシート】
.wrapper {
display: inline-block;
background: #cccccc;
padding: 6px;
font-size: 10pt;
line-height: 30px;
text-align: center;
color: #ffffff;
}
.left-box {
width: 100px;
height: 100px;
background: #000000;
float: left;
}
.right-box {
width: 100px;
height: 100px;
background: #666666;
float: left;
}
【HTML】
<div class="wrapper">
<div class="left-box">ボックスA</div>
<div class="right-box">ボックスB</div>
</div>
<div class="wrapper">
<div class="left-box">ボックスA</div>
<div class="right-box">ボックスB</div>
</div>
●Operaの場合
floatがクリアされているので、親ボックスに子ボックス(A、B)の高さが反映され、背景がきちんと表示されている。さらに、このセットを繰り返しているので、親ボックスはインラインに流し込まれ、横に並ぶ。
●IEの場合
こちらもfloatはクリアされているが、親ボックスはあくまでブロック要素として、横いっぱいに広がり、縦に並ぶ。
●Firefoxの場合
floatはクリアされないので、親ボックスに子ボックスの高さは反映されず、さらにボックスBの右に次のボックスが回り込んでしまう。
ここで、clearfixの記述を思い出してみよう。
IE7 & MacIE対策用にdisplay: inline-blockを指定した後、いわゆるバックスラッシュハックを使ってMacIEを除外した上で、display: blockに戻す。OperaやSafariでは、inline-blockのままでは具合が悪いからだ(MacIEでもinline-block指定による弊害がないわけではない。ブロック要素ではなくなってしまうので、例えばmargin: autoを使ったセンター揃えなどはできなくなってしまう)。
では、IE7はどうなるのか。IE7用にdisplay: inline-blockを指定しておいて、それをまたdisplay: blockに戻してしまうのはどういうことなのか。
実は、IE6以降では、いったんdisplay: inline-blockを指定して } で閉じた後、あらためてdisplay: blockとしても上書きされない、というか、floatのクリアに関してdisplay: inline-blockの指定は生きたままなのである(※)。試しに、先ほどのソースに、親ボックスへのdisplay: block指定を追加してみよう。
【スタイルシート】
.wrapper {
display: inline-block;
background: #cccccc;
padding: 6px;
font-size: 10pt;
line-height: 30px;
text-align: center;
color: #ffffff;
}
.wrapper {
display: block;
}
以下、その2と同じ【HTML】
その2と同じ
●Operaの場合
display: blockと上書きされ、Firefoxの時と同じ表示になる。
●IEの場合
display: inline-blockの指定が生きており、その2と表示は変わらない。
これはIEのバグなんだろうか、仕様なんだろうか。とにもかくにも、この奇妙な振る舞いのおかげで、inline-blockがclearfixにおけるIE7対策として有効に機能しているわけだが、何だかスッキリしない話ではある。
※ } で閉じる前にdisplay: blockとすれば上書きされる。また、インライン要素にinline-block指定した場合は、 } で閉じた後でも、display: blockとすれば上書きされ、完全なブロック要素になる。
【追記】
inline-blockに対応しているのはIE6.0以降と書いたが、evolt.org - Browser Archiveより旧バージョンのIEを入手し、検証を試みたところ、インライン要素へのwidth、heightの指定についてはIE5.0以降、floatのクリアおよび「display: blockとしても上書きされない」という現象についてはIE5.5以降で確認できた。さらに、floatのクリアの件に関しては、hasLayoutというIE独自のプロパティが関係しているらしいこともわかってきた。
hasLayoutとは、IE(5.5以降)が内部的に持つ読み込みのみのプロパティで、その要素がレイアウトを持っているかどうかを示すもの。デフォルトの値はfalse(レイアウトを持っていない)で、ある種のCSSプロパティがトリガーとなって、true(レイアウトを持っている)となる。例えば、height(auto以外の値)、width(auto以外の値)、zoom(すべての値)などで、display(値がinline-blockの時)もそのひとつだ。そして、hasLayoutがtrueと判断されると、例のfloatがクリアされる(のと同じ)現象が起きるのである。いわゆるHolly Hackにおいてheight: 1%と記述するのも、このhasLayoutが背景にあるわけだ。
したがって、「display: blockとしても上書きされない」という件についても、display: inline-blockによって、いったんhasLayoutの値がtrueになると、再びdisplay: blockに戻しても(つまり上書きはされている)、hasLayoutはtrueのまま、ということなのだろうと想像できる。
# hasLayoutに関する参考ページ
hasLayout Property
HasLayout Overview
(last modified: 09/12/2008)
このエントリーのトラックバックURL:
http://norisfactory.com/mt/mt-tb.cgi/39
- HTML5対応版clearfix(予告)
- clearfixの決定版を作る -Mac IE編-
- clearfixの決定版を作る -IE編-
- inline-blockの奇妙な世界
- clearfixの決定版を作る -モダンブラウザ編-
- floatと一緒にwidthも指定しないと回り込まない
- ひとつの要素にfloatとmarginを同時に設定すると位置がずれる
- floatを繰り返すとレイアウトがくずれる
- 要素を左右に隙間なく配置することができない
- 「font-family: 細明朝体」でスタイル指定が無視される
- font-sizeを%で指定すると、ある値でサイズの逆転が起きる
- マージンをまとめて設定するとテーブルはセンタリングされない
- コメントで「表」の字を使うと直後のスタイル指定が無効になる
このサイトは、Creative Commons License のもとにライセンスされています。
Powered by
Movable Type 3.37