Margin Collapse

とてつもなく興味深いので、スタイルシートを使ってデザインをやっている方で、特に「ウガ〜!」と思ったことのある方は是非読んでみるととてもためになるかと思います!。

エレメントの上下のマージンは、隣り合う(というと左右のような雰囲気ですが、上下)場合には噛み合って、結果的には大きい方のマージンが取られるように見えるというのはご承知の通りです。しかしこのマージンの"Collapsion"、とかく怪しい(ように見えてしまう)実装が多く、「ふぬぬぬぬぬ…」となった後、「ウゴ〜!」となることが大変多い、とても扱いづらいたぐいのものでございます。

上記のサイトのアンディ兄さんが、そのあたりの悩みをもう音が出るくらいにばっさりと一刀両断!。大解決でございます。わたくしちょっと泣けてきました。ブラウザのバグを疑う前に、自分を疑え。テーブルレイアウト、JavaScriptと学んできたその教訓を、またここで身に染みて感じる冬のある夜でございます。簡単な英語なのでざっとサンプル見ながら読むといいと思いますが、早い話が、

みんなマージンのCollapsionって、隣り合うエレメント同士で起こると思ってるだろうけど、違うんだぜ。親と子の関係(入れ子の関係)のエレメント同士でも起こるんだ。(包み込むエレメントの上下マージンと、包み込まれる側の上下マージンは、かみ合いあって大きい方の分だけ、親の隣人から突っ張られる。サンプルを見ると、ちゃんと子供側の左右のマージンはばっちり親の左右から張られているのがわかると思います。)

さてはて、上のサンプルで、オレ、エレメントを三つ入れ子にして、一番外側にボーダー付けてるわけだけど、これ、単に見やすくしようってためなんかじゃないんだぜ?。へっ。お前らとんだ甘ちゃんだぜ。ボーダー外してみると、ほら、一番外側のエレメントのマージンも、子と孫のマージンと一緒にCollapseするようになっただろうが。(ボーダーを付けると、入れ子関係のマージンCollapsionを解除できる)

最後に、floatしたエレメント(あ)の次に、clearをかけたエレメント(い)を置いた場合のマージンだけどさ。これまたトリッキー。(い)のマージンは20pxなんだけど、(あ)との間の隙間はあきらかに20pxじゃない。これはなぜかというと、clearするエレメント(この場合(い))は、clear対象になった一つ上隣のfloatエレメントにかぶらないように、CSSで指定したマージンの他に、別の処理でマージンをいったん計算するわけなんだな。そんでもって、その指定されたマージンと、ブラウザが計算したマージンの間でCollapsionが起こって、大きい方(この場合、自分で指定したマージン)が勝って、20pxとなるわけです。しかし、このマージンの始点となる位置ってのは、floatエレメント(あ)のtop位置になるらしく、(あ)のheightは今17pxくらいだから、そんでもって、結果として変な3pxくらいの隙間になってしまうという…。最後素の言葉になるくらい、ややっこしいですね…。

というようなわけで、最後の奴なんかはさっぱり意図がわかんないですけど、そういうことであれば!。という感じですね。見たところ、IE6/WinとFirebird0.7/Winは全部同じようにレンダリングしてました。floatがからむので、IE/Winはかなり、キャッシュの状態とかでもかなり変わってくると思うけど…。