はじめに

CSSでレイアウトを組んでいると、「要素のサイズが思った通りにならない」「要素間の間隔が意図したものと違う」といった問題に直面することがあります。これらの問題の多くは、CSSボックスモデルの理解不足が原因です。

ボックスモデルは、すべてのHTML要素がどのようにサイズを持ち、どのように配置されるかを定義するCSSの根幹となる概念です。この仕組みを正しく理解することで、レイアウト崩れを防ぎ、思い通りのデザインを実現できるようになります。

本記事では、CSSボックスモデルについて以下の内容を解説します。

  • ボックスモデルの4つの領域(content・padding・border・margin)
  • box-sizingプロパティによるサイズ計算方法の違い
  • マージンの相殺(Margin Collapse)の仕組みと対処法
  • 実務で役立つベストプラクティス

前提条件

本記事を読み進めるにあたり、以下の知識があることを前提としています。

  • HTMLの基本的なタグ構造
  • CSSの基本構文(セレクタ・プロパティ・値の関係)
  • ブラウザの開発者ツールの基本操作

動作確認環境

  • Google Chrome 131以降
  • Firefox 133以降
  • Safari 18以降
  • Microsoft Edge 131以降

ボックスモデルとは

ブラウザのレンダリングエンジンは、ドキュメントをレイアウトする際、すべてのHTML要素を長方形のボックスとして表現します。このボックスの構造を定義しているのがCSSボックスモデルです。

MDN Web Docsでは、ボックスモデルを次のように説明しています。

ドキュメントをレイアウトする際、ブラウザのレンダリングエンジンは、標準的なCSSの基本ボックスモデルに従って、各要素を長方形のボックスとして表現します。CSSはこれらのボックスのサイズ、位置、およびプロパティ(色、背景、境界線のサイズなど)を決定します。

ボックスモデルの4つの領域

すべてのボックスは、4つの領域(エリア)で構成されています。内側から順に、content(コンテンツ)、padding(パディング)、border(ボーダー)、margin(マージン)です。

graph TB
    subgraph margin["Margin(マージン)"]
        subgraph border["Border(ボーダー)"]
            subgraph padding["Padding(パディング)"]
                content["Content(コンテンツ)"]
            end
        end
    end
    style margin fill:#ffcccc,stroke:#cc0000
    style border fill:#ffdd99,stroke:#cc6600
    style padding fill:#ccffcc,stroke:#009900
    style content fill:#cceeff,stroke:#0066cc

それぞれの領域について詳しく見ていきましょう。

Content(コンテンツ領域)

コンテンツ領域は、テキスト、画像、動画などの実際のコンテンツを含む最も内側の領域です。その寸法はコンテンツ幅(content width)とコンテンツ高さ(content height)で表されます。

コンテンツ領域のサイズは、widthheightmin-widthmax-widthmin-heightmax-heightプロパティで明示的に指定できます。

1
2
3
4
.box {
  width: 300px;   /* コンテンツ幅 */
  height: 200px;  /* コンテンツ高さ */
}

Padding(パディング領域)

パディング領域は、コンテンツ領域の外側を囲む余白です。要素の背景色や背景画像はパディング領域まで適用されます。

パディングの太さは、padding-toppadding-rightpadding-bottompadding-leftの各プロパティ、またはpaddingショートハンドプロパティで指定します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
.box {
  /* 個別指定 */
  padding-top: 10px;
  padding-right: 20px;
  padding-bottom: 10px;
  padding-left: 20px;
  
  /* ショートハンド(上 右 下 左) */
  padding: 10px 20px 10px 20px;
  
  /* ショートハンド(上下 左右) */
  padding: 10px 20px;
  
  /* ショートハンド(全方向同じ値) */
  padding: 10px;
}

パディングには負の値を指定できません。

Border(ボーダー領域)

ボーダー領域は、パディング領域の外側を囲む境界線です。要素の視覚的な境界を表現するために使用されます。

ボーダーの太さはborder-widthプロパティで、スタイルはborder-styleプロパティで、色はborder-colorプロパティで指定します。borderショートハンドプロパティを使用して一括指定することもできます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
.box {
  /* 個別指定 */
  border-width: 2px;
  border-style: solid;
  border-color: #333333;
  
  /* ショートハンド(幅 スタイル 色) */
  border: 2px solid #333333;
  
  /* 各辺を個別に指定 */
  border-top: 1px solid #000000;
  border-bottom: 3px dashed #666666;
}

Margin(マージン領域)

マージン領域は、ボーダー領域の外側にある余白で、要素と隣接する要素との間隔を確保するために使用されます。マージン領域は透明であり、背景色や背景画像は適用されません。

マージンの太さは、margin-topmargin-rightmargin-bottommargin-leftの各プロパティ、またはmarginショートハンドプロパティで指定します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
.box {
  /* 個別指定 */
  margin-top: 20px;
  margin-right: 10px;
  margin-bottom: 20px;
  margin-left: 10px;
  
  /* ショートハンド(上 右 下 左) */
  margin: 20px 10px 20px 10px;
  
  /* ショートハンド(上下 左右) */
  margin: 20px 10px;
  
  /* ショートハンド(全方向同じ値) */
  margin: 20px;
  
  /* 左右中央揃え */
  margin: 0 auto;
}

パディングと異なり、マージンには負の値を指定できます。負のマージンを使用すると、要素を通常の位置から移動させることができます。

ボックスサイズの計算方法

要素の実際のサイズを理解するには、ボックスモデルの各領域がどのようにサイズに影響するかを知る必要があります。

デフォルトのサイズ計算

デフォルトでは、widthheightプロパティはコンテンツ領域のサイズのみを指定します。そのため、要素が実際に占める領域は、コンテンツサイズにパディングとボーダーを加えたものになります。

1
2
3
4
5
6
.box {
  width: 300px;
  height: 200px;
  padding: 20px;
  border: 5px solid #333333;
}

この場合、要素が実際に占める幅と高さは次のように計算されます。

実際の幅 = width + padding-left + padding-right + border-left + border-right
        = 300px + 20px + 20px + 5px + 5px
        = 350px

実際の高さ = height + padding-top + padding-bottom + border-top + border-bottom
          = 200px + 20px + 20px + 5px + 5px
          = 250px

この計算方法は直感的ではなく、レイアウト設計時に混乱を招くことがあります。

開発者ツールでボックスモデルを確認する

ブラウザの開発者ツールを使用すると、要素のボックスモデルを視覚的に確認できます。

  1. 確認したい要素を右クリックし、「検証」または「要素を調査」を選択します
  2. 「Elements」タブで要素を選択した状態で、「Computed」タブを開きます
  3. ボックスモデルの図が表示され、各領域のサイズを確認できます

開発者ツールのボックスモデル図では、コンテンツ領域が青、パディングが緑、ボーダーが黄色、マージンがオレンジ色で表示されます。

box-sizingプロパティ

box-sizingプロパティは、widthheightがどの領域を基準にサイズを計算するかを制御します。このプロパティを理解することで、サイズ計算を直感的に行えるようになります。

content-box(デフォルト値)

content-boxはCSS標準で定義された初期値およびデフォルト値です。widthheightはコンテンツ領域のサイズのみを指定し、パディングとボーダーは含みません。

1
2
3
4
5
6
7
.content-box-example {
  box-sizing: content-box; /* デフォルト値 */
  width: 200px;
  height: 100px;
  padding: 20px;
  border: 5px solid #333333;
}

この場合の実際のサイズは次の通りです。

実際の幅 = 200px + 20px + 20px + 5px + 5px = 250px
実際の高さ = 100px + 20px + 20px + 5px + 5px = 150px

border-box

border-boxを指定すると、widthheightはボーダー領域までを含んだサイズを指定します。パディングとボーダーはコンテンツ領域の内側に収まるよう計算されます。

1
2
3
4
5
6
7
.border-box-example {
  box-sizing: border-box;
  width: 200px;
  height: 100px;
  padding: 20px;
  border: 5px solid #333333;
}

この場合の実際のサイズと内部のサイズは次の通りです。

実際の幅 = 200px(指定した通り)
実際の高さ = 100px(指定した通り)

コンテンツ領域の幅 = 200px - 20px - 20px - 5px - 5px = 150px
コンテンツ領域の高さ = 100px - 20px - 20px - 5px - 5px = 50px

content-boxとborder-boxの比較

両者の違いを視覚的に理解するために、同じCSSプロパティを適用した例を見てみましょう。

1
2
<div class="content-box">Content box</div>
<div class="border-box">Border box</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
div {
  width: 200px;
  height: 100px;
  padding: 20px;
  border: 8px solid #5b6dcd;
  background: #fffacd;
  margin-bottom: 20px;
}

.content-box {
  box-sizing: content-box;
  /* 実際の幅: 200 + 40 + 16 = 256px */
  /* 実際の高さ: 100 + 40 + 16 = 156px */
}

.border-box {
  box-sizing: border-box;
  /* 実際の幅: 200px */
  /* 実際の高さ: 100px */
  /* コンテンツ幅: 200 - 40 - 16 = 144px */
  /* コンテンツ高さ: 100 - 40 - 16 = 44px */
}

border-boxを使用すると、指定したwidthheightがそのまま要素の最終的なサイズになるため、レイアウト計算が容易になります。

実務での推奨設定

現代のWeb開発では、すべての要素にbox-sizing: border-boxを適用することが一般的です。これにより、サイズ計算が直感的になり、レイアウト崩れを防ぎやすくなります。

以下は、リセットCSSやノーマライズCSSでよく使用されるパターンです。

1
2
3
*, *::before, *::after {
  box-sizing: border-box;
}

この設定により、すべての要素(擬似要素を含む)でborder-boxが適用されます。

一部の要素(<table><select><button>、およびcheckboxradiobuttonsubmitresetタイプの<input>など)は、ブラウザのデフォルトスタイルとしてborder-boxが適用されています。

マージンの相殺(Margin Collapse)

マージンの相殺は、CSSボックスモデルの中でも特に理解しにくい概念の一つです。隣接するブロック要素の垂直方向のマージンが、個別に適用されるのではなく、1つのマージンに統合される現象です。

マージンの相殺とは

ブロック要素の上下のマージンは、特定の条件下で結合(相殺)されることがあります。相殺後のマージンサイズは、結合されたマージンのうち最も大きい値(両者が等しい場合はその値)になります。

MDN Web Docsでは、マージンの相殺を次のように説明しています。

ブロックの上下のマージンは、時々、最も大きな個々のマージン(または等しい場合は1つのマージン)のサイズを持つ単一のマージンに結合(相殺)されます。

マージンの相殺が発生するケース

マージンの相殺は、以下の3つの基本的なケースで発生します。

隣接する兄弟要素

隣接する兄弟要素間では、上の要素の下マージンと下の要素の上マージンが相殺されます。

1
2
<p class="first">最初の段落</p>
<p class="second">2番目の段落</p>
1
2
3
4
5
6
7
8
9
.first {
  margin-bottom: 30px;
}

.second {
  margin-top: 20px;
}

/* 結果: 2つの要素間のマージンは30px + 20px = 50pxではなく、30px(大きい方)になる */

親要素と最初/最後の子要素

親要素と子要素の間に境界線、パディング、インラインコンテンツがない場合、親のmargin-topと最初の子のmargin-top、または親のmargin-bottomと最後の子のmargin-bottomが相殺されます。

1
2
3
<div class="parent">
  <p class="child">子要素の段落</p>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
.parent {
  margin-top: 20px;
  /* border、padding、インラインコンテンツなし */
}

.child {
  margin-top: 30px;
}

/* 結果: 親の上にできるマージンは30px(子のmargin-topが親の外に飛び出す) */

空のブロック要素

境界線、パディング、インラインコンテンツ、heightmin-heightがないブロック要素では、その要素自身のmargin-topmargin-bottomが相殺されます。

1
2
3
4
5
6
7
.empty-block {
  margin-top: 20px;
  margin-bottom: 30px;
  /* コンテンツなし、height未指定 */
}

/* 結果: この要素が占めるマージン領域は30px(大きい方)になる */

マージンの相殺の注意点

マージンの相殺について、いくつかの重要な注意点があります。

  1. 相殺は垂直方向のみで発生します。 水平方向のマージンは相殺されません。

  2. 負のマージンが関係する場合、相殺後のマージンは最大の正のマージンと最小(最も負)の負のマージンの合計になります。

  3. すべてのマージンが負の場合、相殺後のマージンは最小(最も負)のマージンになります。

  4. floatまたはabsoluteで配置された要素のマージンは相殺されません。

  5. FlexboxやGridコンテナ内の要素ではマージンの相殺は発生しません。

マージンの相殺を防ぐ方法

マージンの相殺が意図しない結果をもたらす場合、以下の方法で防ぐことができます。

親子間の相殺を防ぐ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
/* 方法1: パディングを追加 */
.parent {
  padding-top: 1px; /* またはpadding-bottom */
}

/* 方法2: ボーダーを追加 */
.parent {
  border-top: 1px solid transparent;
}

/* 方法3: 新しいブロックフォーマティングコンテキストを作成 */
.parent {
  overflow: hidden; /* または auto */
}

/* 方法4: displayプロパティを変更 */
.parent {
  display: flow-root; /* モダンな方法 */
}

FlexboxまたはGridを使用

FlexboxやGridレイアウト内ではマージンの相殺が発生しないため、これらのレイアウト手法を使用することで問題を回避できます。

1
2
3
4
5
6
7
8
9
.container {
  display: flex;
  flex-direction: column;
}

.container > * {
  margin: 20px 0;
  /* 隣接する要素間でもマージンは相殺されない */
}

実践的なボックスモデルの活用

ボックスモデルの理解を実務に活かすための具体的なパターンを紹介します。

パターン1: カード型コンポーネント

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
.card {
  box-sizing: border-box;
  width: 100%;
  max-width: 400px;
  padding: 24px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  margin-bottom: 16px;
  background: #ffffff;
}

.card-title {
  margin: 0 0 16px 0; /* 上マージン0で親との相殺を防ぐ */
  padding: 0;
}

.card-content {
  margin: 0;
  padding: 0;
}

パターン2: 等間隔のグリッドレイアウト

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
.grid-container {
  display: flex;
  flex-wrap: wrap;
  margin: -8px; /* 子要素のマージンを打ち消す */
}

.grid-item {
  box-sizing: border-box;
  width: calc(33.333% - 16px);
  margin: 8px;
  padding: 16px;
  border: 1px solid #cccccc;
}

パターン3: 全幅の背景を持つセクション

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
.section {
  box-sizing: border-box;
  width: 100%;
  padding: 60px 20px;
  margin: 0;
  background: #f5f5f5;
}

.section-inner {
  box-sizing: border-box;
  max-width: 1200px;
  margin: 0 auto; /* 左右中央揃え */
  padding: 0;
}

よくある問題と解決策

問題1: 要素が親をはみ出す

width: 100%paddingを同時に指定すると、content-boxの場合は親要素をはみ出します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
/* 問題のあるコード */
.child {
  width: 100%;
  padding: 20px;
  /* 実際の幅 = 100% + 40px となり、親をはみ出す */
}

/* 解決策 */
.child {
  box-sizing: border-box;
  width: 100%;
  padding: 20px;
  /* 実際の幅 = 100%(パディングは内側に収まる) */
}

問題2: 画像のサイズが意図通りにならない

<img>要素もボックスモデルに従います。

1
2
3
4
5
6
7
img {
  box-sizing: border-box;
  max-width: 100%;
  height: auto;
  padding: 0;
  border: none;
}

問題3: マージンが意図通りに適用されない

マージンの相殺が原因である可能性があります。開発者ツールで実際のマージンを確認し、必要に応じて相殺を防ぐ対策を講じてください。

ボックスモデルのベストプラクティス

実務でボックスモデルを扱う際に推奨される設計指針をまとめます。

  1. グローバルにbox-sizing: border-boxを設定する

    • すべての要素で直感的なサイズ計算を実現できます
  2. マージンの方向を統一する

    • 垂直方向のマージンは下方向(margin-bottom)のみに統一すると、マージンの相殺による予期せぬ問題を減らせます
  3. コンポーネントにはマージンを設定しない

    • 再利用可能なコンポーネントには外側のマージンを設定せず、親要素や配置用のラッパーでマージンを制御します
  4. 開発者ツールを活用する

    • レイアウトに問題がある場合は、開発者ツールでボックスモデルを確認する習慣をつけましょう
  5. FlexboxやGridを積極的に使用する

    • モダンなレイアウト手法を使用することで、マージンの相殺問題を回避しやすくなります

まとめ

CSSボックスモデルは、Webレイアウトの基盤となる重要な概念です。本記事で解説した内容を振り返ります。

  • ボックスモデルの4つの領域: content(コンテンツ)、padding(パディング)、border(ボーダー)、margin(マージン)が内側から外側に向かって構成されています
  • box-sizingプロパティ: content-box(デフォルト)はコンテンツのみ、border-boxはボーダーまでを含めたサイズ計算を行います。実務ではborder-boxの使用が推奨されます
  • マージンの相殺: 垂直方向の隣接するマージンは1つに統合されます。FlexboxやGridを使用するか、パディング・ボーダーを追加することで防げます

ボックスモデルを正しく理解し、box-sizing: border-boxをグローバルに適用することで、レイアウト崩れの多くを未然に防ぐことができます。開発者ツールを活用しながら、実際のボックスサイズを確認する習慣を身につけましょう。

参考リンク