すべてのボックスを作る 4 つの層
ページ上のすべての要素は、内側から順に次の 4 層でできた長方形として描画されます:
- content (内容): テキスト、画像、子要素。サイズは
widthとheightで決まります。 - padding (内側の余白): ボックスの内側で、内容と border の間の空間。要素の背景が見えます。
- border (枠線): padding を囲む線。
- margin (外側の余白): border の外側の空間で、ほかのボックスを押しのけます。常に透明です。
例では各層を色分けしています。内容は青、padding は緑、border は濃い色、ボックスの周りのオレンジ色の領域が margin です (margin そのものは透明なので、囲みの要素で描いています)。
ボックスの下の行はブラウザが測った値です: 160 + 20 + 20 + 10 + 10 = 220px。margin がその両側にさらに 24px ずつ加わりますが、ボックスの外側なので 220 には含まれません。
幅の計算: content-box と border-box
初期状態 (box-sizing: content-box) では、width は内容だけを指定します。padding と border はその上に加わるので、ボックスは書いた数値より広くなります。box-sizing: border-box では width がボックス全体を表し、padding と border の分だけ内容が縮みます。
content-box (初期値) | border-box | |
|---|---|---|
width が表すもの | 内容 | 内容 + padding + border |
width: 200px; padding: 20px; border: 5px | 幅 250px | 幅 200px |
| そのときの内容の領域 | 200px | 150px |
| margin | 外側で、数えない | 外側で、数えない |
border-box のリセット
border-box にするとサイズの計算が合うので、ほぼすべての現代的なスタイルシートは次のルールから始まります:
*,
*::before,
*::after {
box-sizing: border-box;
}
いちばん効くのはパーセントのときです。content-box では、padding を持つ width: 50% の 2 つの列は 1 行に収まりません。それぞれが 50% に padding を足した幅になるからです:
(HTML コメントは inline-block の列の間の空白を消しています。そうしないと数ピクセル余分に加わります。)
DevTools でボックスモデルを見る
どのブラウザもボックスモデルを図で表示してくれます。要素を右クリックして「検証」を選び、Computed タブ (Firefox ではレイアウト) を開くと、中央に内容のサイズ、その周りに padding、border、margin の値が図で表示されます。Elements パネルで要素にマウスを乗せると、ページにも色が付きます。内容は青、padding は緑、margin はオレンジです。
インラインボックスはルールが違う
上のボックスモデルは、<div> や <p> などのブロックボックスの話です。<span>、<a>、<strong> などのインライン要素はテキストの行の中で折り返し、縦方向の空間を別の扱いにします:
| プロパティ | インライン要素での動作 |
|---|---|
width, height | 無視される |
| 横方向の padding、border、margin | 適用され、隣を横に押す |
| 縦方向の padding と border | 描画されるが、上下の行は押さない |
| 縦方向の margin | 無視される |
display: inline-block にすると、行の中の要素でも完全なボックスモデルになります。幅、高さ、padding、margin がすべて空間を占めます。各層の詳細は CSS padding と CSS margin を参照してください。
よくある間違い
- 固定幅のボックスに padding を足して、広がった理由がわからない。
content-boxでは padding と border がwidthに加わります。border-boxを使いましょう。 - margin に背景色が付くと思う。 margin は常に透明です。色の付いた余白には padding を使います。
- インライン要素に
heightや縦の margin を指定する。 何も起きません。display: inline-blockかblockを使いましょう。 - 計算で border を忘れる。
content-boxでは、width: 100%の要素に 1px の border を付けると 2px はみ出し、横スクロールバーが出ることがあります。 - margin と padding を混同する。 短く言えば、padding は border の内側、margin は外側です。margin と padding の違い のページで並べて比較しています。
よくある質問
CSS のボックスモデルとは何ですか?
すべての要素は 4 層の長方形のボックスとして描画される、というルールです。中身 (content)、その周りの padding、padding を囲む border、border の外側の margin です。CSS の幅、高さ、余白はすべてこれらの層に対して指定します。
box-sizing: border-box は何をしますか?
width と height に padding と border を含めるようにします。padding: 20px と 5px の border を持つ width: 200px のボックスはちょうど 200px 幅になり、中身の領域は 150px に縮みます。初期値の content-box では padding と border が上乗せされ、250px になります。
要素の全体の幅はどう計算しますか?
初期値の content-box では、width + 左右の padding + 左右の border です。border-box では width だけです。どちらの場合も margin はボックスの外側なので、要素自体の幅ではなく、要素が占める空間に加わります。
margin はボックスモデルに含まれますか?
含まれます。いちばん外側の層ですが、常に透明で、要素自体の幅や背景には数えられません。隣のボックスを押しのけるだけです。
すべての要素に box-sizing: border-box を指定すべきですか?
ほとんどのプロジェクトがそうしています。スタイルシートの先頭に *, *::before, *::after { box-sizing: border-box; } を書きます。パーセントの幅と padding が思ったとおりに合計され、Bootstrap や Tailwind などのフレームワークも同じリセットを含んでいます。