マージンの相殺について
上下のマージンは相殺される仕組みになっています。相殺によって、少ない方の数値が打ち消されます。
次のような例を考えてみましょう。
CSSの設定
#first { margin:20px 0; } #second { margin:30px 0; }
HTMLの設定
<div id="first">ああああああ</div> <div id="second">いいいいいい</div>
上の例では最初のdivのマージンは上下20px、次のdivのマージンは30pxです。「ああああああ」と「いいいいいい」の間には50pxのマージンが空きそうですが、実際は30pxしか空きません。相殺によって、少ない方の数値が打ち消されたのです。これがマージンの相殺です。
ブロック要素では通常フローしたブロック要素は必ずその下に次のブロック要素が来ます。その為通常フローしたブロック要素同士の場合は上下のマージン相殺しか起こりません。つまり横には並ばないので左右のマージン相殺はそもそも起こらないのです。
ではフロートして横並びにした場合は親、子に関わらずmarginを指定している要素に、floatを適用すると相殺をしなくなります。
ここまでは少し勉強した方はよくご存知のことですね。
入れ子状態のマージンの相殺について
悩ましいのは親子関係の入れ子状態にある場合のマージン相殺です。上下のマージンの相殺はちょっと複雑な挙動になります。ただし、横方向のマージン相殺はありません。
次の例をみてください
上のサンプルのソースは以下です。
CSS側
#first { background-color: #CFF; width: 300px; height: 300px; } #sec { background-color: #FFC; border: 1px solid #F30; margin-top: 30px; }
HTML側
<div id="first"> <div div="sec">この部分がヘッダー</div> </div>
ブロック要素を入れ子状態にして内側のブロック要素「この部分がヘッダー」に上マージンを設定して30pxだけ空間を空けたいと思うのだが、ブロック内でマージンがかかりません。本来なら30pxだけ空間が空いて水色の背景が30pxだけ見えるはずなのですが、「この部分がヘッダー」に変化は見られません。
そして、さらに外側のマージンよりも内側のマージンが大きければ内側のマージン分だけ、ここでは30pxだけ外側にマージンがついてしまうという変な挙動になってしましいます。
この入れ子状態のマージン相殺は制作の時の悩みの種になることが多いです。しっかり理解しておきましょう。
解決方法は外側のブロック要素にボーダーをつけるか、paddingをつけます。
先ほどの例で外側のdivにボーダーをつけてみましょう。以下のとおりです。
#first { background-color: #CFF; border:solid #000 1px; width: 300px; height: 300px; } #sec { background-color: #FFC; border: 1px solid #F30; margin-top: 30px; }