CSSボックスモデル入門
margin・padding・borderを正しく理解する
CSSのボックスモデルの仕組みを基礎から解説。margin、padding、border、box-sizing、displayプロパティまで、レイアウトの基本を学べます。
こんな人向けの記事です
- CSSのmarginとpaddingの違いを正しく理解したい
- box-sizingの設定を知りたい
- マージンの相殺を理解したい
Step 1ボックスモデルとは
CSSでは、すべてのHTML要素は「ボックス」として扱われます。ボックスモデルは、要素の表示領域をcontent(内容)、padding(内側の余白)、border(枠線)、margin(外側の余白)の4つの層で構成します。
<div class="box">ボックスモデルの例</div>
.box {
width: 200px; /* content の幅 */
padding: 20px; /* 内側の余白 */
border: 3px solid #333; /* 枠線 */
margin: 30px; /* 外側の余白 */
}
| 層 | 役割 | プロパティ |
|---|---|---|
| content | テキストや画像などの内容領域 | width, height |
| padding | contentとborderの間の余白 | padding, padding-top 等 |
| border | ボックスの枠線 | border, border-width 等 |
| margin | 他の要素との間の余白 | margin, margin-top 等 |
width + padding左右 + border左右 になります。例:
width: 200px; padding: 20px; border: 3px solid; → 実際の幅 = 200 + 40 + 6 = 246px
Step 2box-sizing: border-box vs content-box
box-sizing プロパティは、width と height がどの範囲を指すかを制御します。
| 値 | widthに含まれる範囲 | 特徴 |
|---|---|---|
content-box(デフォルト) | contentのみ | padding・borderが加算されて幅が広がる |
border-box | content + padding + border | 指定したwidthを超えない |
content-box(width: 200px → 実際の幅: 246px):
border-box(width: 200px → 実際の幅: 200px):
<div class="content-box">width: 200px</div>
<div class="border-box">width: 200px</div>
/* content-box: 実際の幅 = 200 + 40 + 6 = 246px */
.content-box {
box-sizing: content-box;
width: 200px;
padding: 20px;
border: 3px solid #e74c3c;
}
/* border-box: 実際の幅 = 200px(paddingとborderが内側に収まる) */
.border-box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 3px solid #3498db;
}
border-box を適用するリセットCSSを使います。これにより、widthの計算が直感的になります。
/* 全要素に border-box を適用(推奨リセット) */
*, *::before, *::after {
box-sizing: border-box;
}
Step 3marginの相殺(マージン崩壊)
隣接するブロック要素のmarginは、合算されずに大きい方の値だけが適用されます。これを「マージンの相殺(margin collapsing)」と呼びます。
margin-bottom: 30px と margin-top: 20px の間隔:
実際の間隔は 30px + 20px = 50px ではなく、大きい方の 30px になる
<div class="box-a">margin-bottom: 30px</div>
<div class="box-b">margin-top: 20px</div>
.box-a {
margin-bottom: 30px; /* この値が大きい */
}
.box-b {
margin-top: 20px; /* この値は相殺される */
}
/* 実際の間隔: max(30px, 20px) = 30px */
マージン相殺が起こる条件
| 条件 | 説明 |
|---|---|
| 隣接する兄弟要素 | 上の要素のmargin-bottomと下の要素のmargin-topが相殺 |
| 親子要素 | 親の最初の子のmargin-topが親のmarginと相殺 |
| 空のブロック要素 | 自身のmargin-topとmargin-bottomが相殺 |
マージン相殺を防ぐ方法
/* 方法1: 親要素に overflow を設定 */
.parent { overflow: hidden; }
/* 方法2: 親要素に padding または border を設定 */
.parent { padding-top: 1px; }
/* 方法3: 親要素に display: flow-root を設定(推奨) */
.parent { display: flow-root; }
/* 方法4: flexbox や grid を使う */
.parent { display: flex; flex-direction: column; }
display: flow-root は新しいブロックフォーマティングコンテキスト(BFC)を生成します。副作用なくマージン相殺を防ぐ最もクリーンな方法です。
Step 4paddingとmarginの使い分け
paddingとmarginはどちらも「余白」を作りますが、用途が異なります。
| プロパティ | 位置 | 用途 | 背景色 |
|---|---|---|---|
padding | borderの内側 | 要素の中身と枠線の間隔 | 適用される |
margin | borderの外側 | 要素同士の間隔 | 適用されない(透明) |
paddingで内側に余白(背景色が余白にも適用):
背景色が余白部分にも表示される
marginで外側に余白(背景色は余白に適用されない):
外側の余白は透明
<div class="padding-demo">padding: 30px</div>
<div class="margin-demo">margin: 30px</div>
/* padding: 背景色が余白にも適用される */
.padding-demo {
background: #3498db;
color: white;
padding: 30px;
}
/* margin: 外側の余白は透明 */
.margin-demo {
background: #e74c3c;
color: white;
padding: 10px;
margin: 30px;
}
ショートハンド記法
/* 値1つ: 上下左右すべて同じ */
padding: 20px;
/* 値2つ: 上下 / 左右 */
padding: 10px 20px;
/* 値3つ: 上 / 左右 / 下 */
padding: 10px 20px 30px;
/* 値4つ: 上 / 右 / 下 / 左(時計回り) */
padding: 10px 20px 30px 40px;
/* marginも同じ記法 */
margin: 0 auto; /* 上下0、左右auto(中央寄せ) */
width を指定した上で margin: 0 auto を設定すると、水平方向の中央寄せができます。
Step 5displayプロパティ
display プロパティは、要素がどのように配置されるかを制御します。ボックスモデルの挙動もdisplayの値によって変わります。
| 値 | 特徴 | width/height | margin上下 |
|---|---|---|---|
block | 前後に改行が入る。幅いっぱいに広がる | 指定可能 | 有効 |
inline | テキストのように横に並ぶ | 指定不可 | 無効 |
inline-block | 横に並びつつ、幅・高さを指定可能 | 指定可能 | 有効 |
none | 要素を非表示にする(領域も消える) | - | - |
block(幅いっぱい・前後に改行):
inline(横に並ぶ・幅指定不可):
inline-block(横に並ぶ・幅指定可能):
<!-- block -->
<div class="block-item">block要素A</div>
<div class="block-item">block要素B</div>
<!-- inline -->
<span class="inline-item">inline要素A</span>
<span class="inline-item">inline要素B</span>
<!-- inline-block -->
<span class="ib-item">inline-block A</span>
<span class="ib-item">inline-block B</span>
/* block: 幅いっぱいに広がり、前後に改行 */
.block-item {
display: block;
background: #3498db;
padding: 10px;
}
/* inline: 横に並ぶ、width/height指定不可 */
.inline-item {
display: inline;
background: #e74c3c;
padding: 4px 8px;
}
/* inline-block: 横に並びつつ、width/height指定可能 */
.ib-item {
display: inline-block;
width: 120px;
background: #2ecc71;
padding: 10px;
text-align: center;
}
display: none は要素を完全に消します(領域も消える)。visibility: hidden は見えなくなりますが、要素の領域は残ります。
Step 6overflowの制御
コンテンツがボックスのサイズを超えた場合の表示方法を overflow で制御します。
| 値 | 動作 |
|---|---|
visible(デフォルト) | はみ出して表示される |
hidden | はみ出した部分を非表示にする |
scroll | 常にスクロールバーを表示する |
auto | 必要な場合のみスクロールバーを表示する |
overflow: visible
overflow: hidden
overflow: auto
<div class="overflow-visible">はみ出すテキスト...</div>
<div class="overflow-hidden">はみ出すテキスト...</div>
<div class="overflow-auto">はみ出すテキスト...</div>
.overflow-visible {
width: 140px;
height: 60px;
overflow: visible; /* はみ出して表示(デフォルト) */
}
.overflow-hidden {
width: 140px;
height: 60px;
overflow: hidden; /* はみ出た部分を非表示 */
}
.overflow-auto {
width: 140px;
height: 60px;
overflow: auto; /* 必要時のみスクロールバー */
}
overflow-x と overflow-y を使います。例:
overflow-x: auto; overflow-y: hidden;
/* テキストの省略表示(1行) */
.text-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 横スクロール可能なコンテナ */
.scroll-container {
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
}
まとめボックスモデルのポイント
| トピック | ポイント |
|---|---|
| ボックスモデル | content → padding → border → margin の4層構造 |
| box-sizing | border-box を全要素に適用するのが実務の定番 |
| マージン相殺 | 隣接するmarginは大きい方だけ適用。display: flow-root で防止 |
| padding vs margin | padding = 内側の余白(背景色あり)、margin = 外側の余白(透明) |
| display | block / inline / inline-block でレイアウトの基本を制御 |
| overflow | はみ出し制御。hidden / auto / scroll を使い分ける |