CSS | marginの相殺とは
marginの相殺とは?
まず、marginの相殺とはなんなのか、(気取って)MDN の概要を見てみましょう。
ブロックの top と bottom のマージンは結合される(折り畳まれる (collapsed))ことがあり、結合されるマージンのうち大きなほうのサイズを持った一つのマージンになります。この動作は マージンの相殺 (margin collapsing) として知られています。
あんま、よくわかんないっすね。
では、噛み砕いて説明してみます。
marginには相殺(margin collapsing)と呼ばれる独特のルールがあり、
発生条件は
- ブロックレベルの要素で、かつ
- margin と margin の間に何も無い場合で、かつ
- 上下のmargin同士が直接触れ合っている場合に
相殺が起きます。
この場合、どちらか幅の大きいmarginだけが残り、小さい方は相殺されます(反映されません)。
同じ幅なら片方だけのマージン幅になります。
繰り返しますが、相殺は「上下マージンだけ」「ブロックレベル要素だけ」の場合に起こります。
相殺が起こらないケース
いろいろな場合がありますので、主なものを見ていきましょう。
左右のマージンは相殺されません
上記を見てもわかるように、左右のマージンが相殺されるなら margin-left が10pxでも、margin-right が 20pxなので、margin-left 10pxは相殺されます。ですが、10pxにしたら横幅が増えるので、左右のマージンは相殺されないということがわかります。
親の要素に特定のCSSを適用することで、子の相殺が発生しません。
- border (marginが指定されている方向)
- padding (marginが指定されている方向)
- overflow:hidden, scroll (auto, visibleは適用されない)
親要素に overflow: scroll を当てても同じ挙動をします。
- position:absolute, fixed (relative, staticは適用されない)
(親要素に position:fixed を当てても同じ挙動をします。)
さらに上記以外にも、floatによって相殺が発生しない場合がたくさんあります。
margin と float の関係
marginとfloatは、密接な関係にありますので、合わせて見ていきましょう。
marginのかかっている要素に、floatが隣接している場合
floatが親、子の要素にかかると相殺が発生しません。ただfloatが隣接しているだけなら、marginとfloatで相殺が発生します。以下はその基本的な条件です。
- floatに隣接
- 隣接している要素に、marginが指定されている
- 隣接している要素に、floatが指定されていない
上の条件が全てではありません。様々な影響により、相殺が発生する場合としない場合があるので割愛します。
以下、marginとfloatの相殺の例です。
float: left; にコメントアウトをすると、testクラスのmargin top: 96px;が効くようになります。
img のスタイルに float:left; をコメントアウトすると、floatが無くなるために、
testクラスのdivの margin-topの幅は、写真の底辺から、divまでの幅ということになります。
このfloatとmarginの相殺は、floatを解除するclearプロパティにも関係してきます。
clearは、floatを解除するものではない
「floatを解除する」とよく説明されるclearプロパティですが、clearは、marginの相殺を抑制し、floatの底辺に要素がつくように、margin-topの値を自動調整するような振る舞いを行います。
clear:none;の場合は、通常通りに振舞います。
以下、実例です。
.clearにmargin-topに100pxも指定しています。本来なら、100pxの間隔が空くはずですが、float:leftを指定したimgの底辺にくっついてしまっています。
これはclearによる仕様です。clear:left;を指定したことによって、margin-topが自動調整されて、float:left;の指定された要素の後ろにつきます。
仮に、.clearにmargin-topに1000pxを指定しても、何も変わりません。
さらに、float:right;を指定したピンクの.rightの底辺(marginを含む)には、.clear-rightの上辺が重なっています。この場合、ピンクの.rightの上辺から底辺までのmargin-topを調整している訳ではなく、.clearから.rightの底辺までの距離で、margin-topを調整しています。
clearとmargin-topを同時に適用すると、clearプロパティが優先されるので気をつけて下さい。
相殺を見込んで シンプルな CSSを書けるようになれば、とっても便利ですので、ぜひいろんな事例を覚えましょう。