6日でできる 新HTML&CSS入門|マージン相殺の仕組みと対策

余白が足されない理由を知れば、CSSレイアウトはもっと安心して整えられる。
マージン相殺の仕組みを理解して、思いどおりの間隔を作ろう。

Webページのレイアウトでは、要素と要素の間隔を整えるためにmarginをよく使います。見出しと本文の間を空けたり、カード同士の距離を広げたり、セクションの上下に余白を作ったりするときに、marginはとても便利です。

しかし、上下方向のmarginには少し独特な動きがあります。上の要素にmargin-bottomを指定し、下の要素にmargin-topを指定したとき、2つの値がそのまま足し算されない場合があります。この現象をマージン相殺といいます。

たとえば、上の要素にmargin-bottom: 24px;、下の要素にmargin-top: 48px;を指定した場合、間隔が72pxになるとは限りません。条件によっては、2つのmarginが重なり、大きいほうの48pxだけが間隔として使われます。

最初は少し不思議に感じるかもしれませんが、マージン相殺はCSSの仕様として決められている動きです。仕組みを知っておくと、「なぜ余白が思ったより広がらないのか」「なぜ親要素の外側に余白が出ているように見えるのか」を落ち着いて確認できるようになります。

この記事では、マージン相殺の基本、隣り合うブロック要素で起こるパターン、親子要素で起こるパターン、そして相殺を避けるための考え方を、サンプルコードを使って分かりやすく解説していきます。

マージン相殺とは何か

マージン相殺とは、上下方向に隣り合うmarginが重なり、単純な足し算ではなく、大きいほうの値が有効になる現象です。

CSSでは、ブロック要素を縦に並べたとき、上の要素のmargin-bottomと下の要素のmargin-topがぶつかることがあります。このとき、marginが合計されるのではなく、重なって1つの余白として扱われます。

用語内容
margin-top要素の上側に作る外側余白
margin-bottom要素の下側に作る外側余白
マージン相殺隣り合う上下方向のmarginが重なり、大きいほうの値が残る現象

たとえば、上の要素のmargin-bottomが20px、下の要素のmargin-topが40pxの場合、間隔は60pxではなく40pxになることがあります。

横方向のmargin-leftやmargin-rightでは、通常この相殺は起こりません。マージン相殺で特に注意するのは、上下方向のmarginです。

図1:上下のmarginは足し算されないことがある

この図から分かること

上下に並ぶブロック要素では、margin-bottomとmargin-topが重なり、単純に足し算されない場合があります。上の余白が24px、下の余白が48pxなら、間隔は72pxではなく48pxになることがあります。これがマージン相殺の基本的な考え方です。

基本サンプルでマージン相殺を確認する

まずは、2つのブロック要素を縦に並べて、マージン相殺がどのように見えるかを確認してみましょう。

上のブロックにはmargin-bottom: 24px;を指定し、下のブロックにはmargin-top: 48px;を指定します。本来、単純に足し算されるなら72pxの間隔になりそうですが、実際には大きいほうの48pxが間隔として残ります。

ファイル名: lesson31_1.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>マージン相殺の基本確認</title>
<style>
  .box-top {
    margin-bottom: 24px;
    padding: 16px;
    background-color: #bde7ff;
  }

  .box-bottom {
    margin-top: 48px;
    padding: 16px;
    background-color: #c8f7dc;
  }
</style>
</head>
<body>
  <div class="box-top">
    上のボックス<br>
    margin-bottom: 24px;
  </div>

  <div class="box-bottom">
    下のボックス<br>
    margin-top: 48px;
  </div>
</body>
</html>

ブラウザの表示例

このHTMLをブラウザで表示すると、上のボックスと下のボックスの間隔は、24pxと48pxを足した72pxではなく、48pxになります。

これは、上のボックスの下方向のmarginと、下のボックスの上方向のmarginが重なっているためです。2つのmarginが別々の余白として並ぶのではなく、1つの余白として扱われ、大きいほうの値が使われます。

なぜマージン相殺が起こるのか

マージン相殺は、CSSがブロック要素の上下余白を自然に整理するための仕様です。文章中心のレイアウトでは、見出しや段落が縦に並ぶことが多く、それぞれが上下にmarginを持っていると、すべてを足し算すると余白が大きくなりすぎる場合があります。

そこで、上下方向のmarginがぶつかったときは、重ねて扱う仕組みがあります。これにより、段落や見出しの余白が極端に広がりすぎず、自然な間隔になりやすくなります。

ただし、デザインを細かく調整しているときには、この仕様が原因で「指定した数値どおりに見えない」と感じることがあります。特に、要素同士の間隔を正確に調整したいときには、マージン相殺を意識しておくことが大切です。

隣り合うブロック要素で起こる相殺

マージン相殺の代表的なパターンは、縦に隣り合うブロック要素同士です。上の要素のmargin-bottomと、下の要素のmargin-topが接すると、2つのmarginが相殺されます。

次の例では、上のsectionにmargin-bottom: 32px;を指定し、下のsectionにmargin-top: 56px;を指定しています。

ファイル名: lesson31_2.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>隣接ブロックのマージン相殺</title>
<style>
  .news-box {
    margin-bottom: 32px;
    padding: 12px;
    background-color: #fff6c7;
  }

  .info-box {
    margin-top: 56px;
    padding: 12px;
    background-color: #dffaf4;
  }
</style>
</head>
<body>
  <section class="news-box">
    上のセクション<br>
    margin-bottom: 32px;
  </section>

  <section class="info-box">
    下のセクション<br>
    margin-top: 56px;
  </section>
</body>
</html>

ブラウザの表示例

このサンプルでは、上下のsectionの間隔は32pxと56pxを足した88pxではなく、56pxになります。

大きいほうのmargin-top: 56px;が有効になり、margin-bottom: 32px;は重なって見えなくなります。これが、隣り合うブロック要素で起こる典型的なマージン相殺です。

隣接ブロックで相殺が起こる条件

マージン相殺は、どんな要素でも必ず起こるわけではありません。主に、通常の文書の流れにあるブロック要素が上下に隣り合っているときに起こります。

状況相殺の起こりやすさ
ブロック要素が上下に隣り合っている起こりやすい
上の要素のmargin-bottomと下の要素のmargin-topが接している起こりやすい
横方向のmargin-leftとmargin-right基本的に相殺しない
paddingやborderで間に境界がある相殺しにくい
flexやgridの中の要素通常のブロックとは挙動が変わる

学習の最初は、「上下に並ぶブロック要素のmarginは足し算されないことがある」と覚えておくと十分です。そのうえで、必要に応じて相殺を避ける方法を使うと、レイアウトを調整しやすくなります。

図2:隣接するブロック要素のmargin相殺

この図から分かること

上下に隣り合うブロック要素では、上の要素の下marginと、下の要素の上marginが重なる場合があります。2つのmarginが合計されるのではなく、より大きい値が間隔として残ります。余白を正確に調整したいときは、この動きを意識することが大切です。

親子要素で起こるマージン相殺

マージン相殺は、隣り合う兄弟要素だけでなく、親要素と子要素の間でも起こることがあります。

たとえば、親要素の中に最初の子要素があり、その子要素にmargin-topが指定されている場合です。親要素にborderやpaddingがないと、子要素の上marginが親要素の内側にとどまらず、親要素の外側に出ているように見えることがあります。

これは、親の上端と子の上marginが接しているためです。同じように、最後の子要素のmargin-bottomが、親要素の下側に影響して見えることもあります。

親子間の相殺を確認するサンプル

次の例では、親要素の中に子要素を入れ、子要素に上下のmarginを指定しています。親要素には、あえてborderやpaddingを指定していません。これにより、子要素のmarginが親要素の外側に影響して見える様子を確認しやすくしています。

ファイル名: lesson31_3.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>親子要素のマージン相殺</title>
<style>
  .outer-area {
    background-color: #f2f2f2;
  }

  .parent-box {
    margin-top: 30px;
    margin-bottom: 30px;
    background-color: #e9ecff;
  }

  .child-box {
    margin-top: 40px;
    margin-bottom: 50px;
    background-color: #ffe0e8;
  }
</style>
</head>
<body>
  <div class="outer-area">
    <div class="parent-box">
      <div class="child-box">
        子要素<br>
        margin-top: 40px;<br>
        margin-bottom: 50px;
      </div>
    </div>
  </div>
</body>
</html>

ブラウザの表示例

このサンプルでは、子要素のmargin-topやmargin-bottomが、親要素の内側の余白として見えるのではなく、親要素の外側に影響しているように見える場合があります。

親要素にborderやpaddingがない場合、親の上端と最初の子要素の上margin、または親の下端と最後の子要素の下marginが接し、相殺が起こることがあります。

ここで大切なのは、marginは常に親要素の内側にきれいに収まるとは限らないということです。子要素の余白を親要素の内側に作りたい場合は、marginではなくpaddingを使うほうが分かりやすい場面もあります。

親子間の相殺を防ぐ考え方

親子間のマージン相殺を避けたい場合は、親要素と子要素のmarginが直接接しないようにします。代表的な方法には、親要素にpaddingやborderを付ける、またはoverflowを指定する方法があります。

対策考え方
親要素にpaddingを付けるpadding-top: 1px;親と子のmarginが直接接しにくくなる
親要素にborderを付けるborder: 1px solid transparent;親の端に境界ができる
親要素にoverflowを指定するoverflow: hidden;新しい表示領域として扱われやすくなる
子要素のmarginではなく親要素のpaddingを使うparentにpaddingを指定内側余白として管理しやすい

たとえば、親要素の中で子要素を少し下げたい場合、子要素にmargin-topを付けるよりも、親要素にpadding-topを付けるほうが、意図した見た目になりやすいことがあります。

.parent-box {
  padding-top: 40px;
}

このようにすると、余白は親要素の内側に作られるため、親の外側に余白が出てしまうような見え方を避けやすくなります。

marginとpaddingの役割を分けて考える

マージン相殺で迷ったときは、marginとpaddingの役割を分けて考えると整理しやすくなります。

marginは、要素の外側の余白です。隣の要素との距離を空けるために使います。そのため、上下方向では相殺が起こる場合があります。

paddingは、要素の内側の余白です。内容とborderの間に余白を作るために使います。paddingはmarginのように相殺されません。

使いたい余白向いている指定
要素同士の外側の距離を空けたいmargin
親要素の内側に余白を作りたいpadding
カードの中身を下にずらしたいpadding-top
セクション同士を離したいmargin-topまたはmargin-bottom
相殺を避けて確実に内側余白を作りたいpadding

marginは外側、paddingは内側という基本を押さえると、相殺が起きたときにも原因を探しやすくなります。

図3:親子間の相殺とpaddingによる対策

この図から分かること

親子要素では、子要素のmarginが親要素の外側に影響して見えることがあります。親要素の内側に余白を作りたい場合は、子要素のmarginではなく、親要素のpaddingを使うと安定しやすくなります。マージン相殺を避けたいときは、親と子の余白が直接接しないようにすることが大切です。

マージン相殺が起こりやすい場面

マージン相殺は、Webページのさまざまな場所で起こります。特に、見出し、段落、セクション、カードなどを縦に並べる場面では注意が必要です。

場面起こりやすい内容
見出しと段落を縦に並べるh2のmargin-bottomとpのmargin-topが相殺される
セクション同士を並べる上のsectionのmargin-bottomと下のsectionのmargin-topが相殺される
親要素の先頭に子要素を置く子要素のmargin-topが親の外側に出るように見える
親要素の最後に子要素を置く子要素のmargin-bottomが親の外側に出るように見える

Webページでは、要素を縦に積み重ねるレイアウトが多いため、マージン相殺はとても身近な現象です。特に、CSSをリセットしていない状態では、h1、h2、pなどが標準でmarginを持っていることもあり、意図しない余白に見えることがあります。

マージン相殺を避ける代表的な方法

マージン相殺を避けたい場合は、いくつかの方法があります。どの方法を使うかは、作りたいレイアウトや意図によって変わります。

方法使いどころ
片方の要素だけにmarginを指定するセクション間の余白をシンプルに管理したいとき
paddingを使う親要素の内側に余白を作りたいとき
borderを付ける親子間の相殺を止めたいとき
overflow: hidden;を使う親子間の相殺を避けたいとき
display: flow-root;を使う親要素を独立したブロック整形コンテキストとして扱いたいとき
flexやgridを使うレイアウト全体を現代的に管理したいとき

初心者のうちは、まず「上下の余白は片方の要素にだけ指定する」方法が分かりやすいです。たとえば、セクション同士の間隔は、下の要素のmargin-topではなく、上の要素のmargin-bottomだけで管理する、と決めておくと混乱しにくくなります。

.section {
  margin-bottom: 40px;
}

このようにルールを決めておくと、どのmarginが効いているのか確認しやすくなります。

display: flow-rootを使った相殺対策

少し実践的な方法として、親要素にdisplay: flow-root;を指定する方法もあります。

.parent-box {
  display: flow-root;
}

display: flow-root;を指定すると、その要素は新しいブロック整形コンテキストを作ります。これにより、親子間のmargin相殺を防ぎやすくなります。

古くからある方法としてoverflow: hidden;も使われますが、overflow: hidden;ははみ出した内容を隠してしまうことがあります。そのため、単にレイアウトの独立性を作りたい場合は、display: flow-root;のほうが意図が分かりやすいことがあります。

ただし、学習の最初は、まずpaddingやborderで相殺を止められることを理解するとよいです。そのあとで、必要に応じてdisplay: flow-root;を覚えると、より実践的なCSS設計につながります。

使用するタグとCSSの整理

ここまでに使ったタグとCSSを整理しておきます。

タグ・CSS説明
div汎用的なブロック要素。レイアウト確認やボックス作成でよく使う
sectionセクション単位のまとまりを表すブロック要素
margin-top要素の上側に外側余白を作る
margin-bottom要素の下側に外側余白を作る
padding要素の内側に余白を作る
border要素に枠線を付ける
background-color背景色を指定する
overflow内容がはみ出したときの表示方法を指定する
display: flow-root親子間の相殺を防ぎたいときにも使える表示指定

マージン相殺を理解するときは、margin-topとmargin-bottomの関係をよく見ることが大切です。特に、上下方向の余白が思ったとおりにならないときは、どの要素のmarginが重なっているのかを確認してみましょう。

マージン相殺を理解して余白設計を安定させる

マージン相殺は、CSSを学び始めたばかりのころに戸惑いやすいポイントです。指定したmarginが効いていないように見えたり、親要素の中に余白を入れたつもりなのに外側へ出ているように見えたりすることがあります。

しかし、仕組みを知ってしまえば、原因を見つけやすくなります。上下方向のmarginは足し算されず、大きいほうだけが残る場合があります。親子要素でも、親にpaddingやborderがないと、子要素のmarginが親の外側に影響して見えることがあります。

余白を安定して管理したいときは、外側の距離にはmargin、内側の余白にはpaddingを使うことを意識しましょう。また、必要に応じてborder、overflow、display: flow-rootなどを使うと、相殺を避けながらレイアウトを整えやすくなります。

CSSの余白設計では、数値だけでなく「どの場所の余白なのか」を考えることが大切です。マージン相殺の仕組みを理解しておくと、要素同士の間隔や親子要素の余白を、より落ち着いて調整できるようになります。