CSS実験室

inline-blockの奇妙な世界

inline-blockとは、displayプロパティの値のひとつで、表示形式を「インラインに流し込むことのできるブロック要素」にするためのもの。まともに対応しているのが、OperaとSafari、それになぜかMac版IEくらいというマイナーな存在だが、なかなか興味深い振る舞いをする値なので、いろいろと検証してみた。

まず、「インラインに流し込むことのできるブロック要素」とはどういうものなのかを見てみるために、.inlineblockというクラスを作り、div要素に指定してみた。また、「インラインに流し込むことのできるブロック要素」とは、言い換えれば、「幅と高さを指定できるインライン要素」ということだから、span要素にも指定した。

インラインブロックの検証 その1
【スタイルシート】 .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をクリアできる。このことを次のソースを使って確認してみよう。

インラインブロックの検証 その2
【スタイルシート】 .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指定を追加してみよう。

インラインブロックの検証 その3
【スタイルシート】 .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)

TrackBack

このエントリーのトラックバックURL:
http://norisfactory.com/mt/mt-tb.cgi/39

Post a comment









search

contents
CSS実験室
CSSトラブルシューティング
-- background関連 --
-- float関連 --
-- ソースの記述 --
-- ボックス関連 --
-- 定義リスト関連 --
-- 標準モードと互換モード --
feed
Creative Commons License

このサイトは、Creative Commons License のもとにライセンスされています。

Powered by
Movable Type 3.37