解 説

marginの相殺

通常フローでmargin同士が重なった場合に相殺が起こります。相殺は、数値の大きい方が適用されます。ただし、水平方向(横方向)のマージンは相殺されません。

marginの相殺のサンプル

相殺は入れ子の状態でも、marginが重なれば発生します。
親と子ともにmarginが設定された場合、相殺が発生します。こちらも、数値の大きい方が適用されます。

入れ子状態のマージン相殺サンプル

相殺が起こらないケース

親の要素に以下の設定を行うと相殺は起こりません。

  1. border (marginが指定されている方向)
  2. padding (marginが指定されている方向)
  3. overflow:hidden, scroll (auto, visibleは適用されない)
  4. position:absolute, fixed (relative, staticは適用されない)
  5. 親か子のどちらかでもfloatを指定すると、親子での相殺が起こらない。
  6. floatが指定されると、margin:auto; は絶対的に0になる。
  7. 兄弟同士にfloatが指定されていると、相殺が起こらない。

floatが親、子の要素にかかると相殺が発生しません。
ただfloatが隣接しているだけなら、marginとfloatで相殺が発生します。
以下はその基本的な条件です。

  • 隣接している要素に、marginが指定されている
  • 隣接している要素に、floatが指定されていない

clearについて

clearは、marginの相殺を抑制し、floatの底辺に要素がつくように、margin-topの値をが自動調整するように振る舞います。clearの上に存在する要素に全てfloatがかかっていたらmargin-topの値がいくつでも無視されて、floatの下に付きます。もし、floatの前後に通常フローが存在したなら(隣接するボックス)、その通常フローの下辺からfloatしたボックスの下辺までのマージンがクリアランスとして自動的に取られます。この場合、クリアランスの値よりmargin-topの値が大きければmargin-topの値が取られるようになります。なお自身を包含するブロックのみが存在する場合はその包含ブロックの上辺からクリアランスされます。