CSSのbox-sizingでwidthとpaddingの計算方法を変える(content-box vs border-box)
CSS で width を指定したのに、padding や border を足すと想定より大きくなってしまう。この問題を解決するのが box-sizing プロパティだ。ボックスの「幅」が何を含むかを切り替えることで、レイアウト計算がシンプルになる。
content-box(初期値)
初期値の content-box では、width はコンテンツ領域の幅だけを指す。padding と border は width の外側に追加されるため、実際の描画サイズは width + padding + border になる。
<div class="content-box-demo">
<div class="info">width: 200px</div>
<div class="info">padding: 20px</div>
<div class="info">border: 2px</div>
<div class="info">実際の幅: 244px</div>
</div>.content-box-demo {
box-sizing: content-box;
width: 200px;
padding: 20px;
border: 2px solid #ef4444;
background: #fef2f2;
font-size: 13px;
}
.info {
margin: 4px 0;
}width: 200px に padding 左右 40px と border 左右 4px が加算され、合計 244px で描画される。レイアウトを組むたびにこの計算をするのは手間がかかる。
border-box
border-box を指定すると、width が padding と border を含んだ値になる。つまり width: 200px と書けば、padding や border がどれだけあっても要素の外形は 200px に収まる。
.box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 2px solid #3b82f6;
}
/* 実際の幅は 200px(コンテンツ領域が自動で縮む) */コンテンツ領域は 200 - 40(padding)- 4(border)= 156px に自動調整される。width が最終的な描画幅と一致するため、レイアウトの見通しが格段によくなる。
2 つの違いを視覚的に比較する
width = コンテンツ領域のみ。padding と border は外側に加算される。幅の計算が複雑になりやすく、レイアウト崩れの原因になることが多い。
width = コンテンツ + padding + border の合計。指定した幅がそのまま要素の外形になる。直感的で計算が簡単。
全称セレクタでリセットする
実務では、すべての要素に border-box を適用するのが標準的なやり方だ。CSS リセットや Normalize.css にもこの指定が含まれていることが多い。
*,
*::before,
*::after {
box-sizing: border-box;
}疑似要素(::before, ::after)にも適用するのがポイントだ。これを忘れると、疑似要素だけ content-box のままになり、微妙なレイアウトのずれが発生する。
CSS のリセットファイルの冒頭にこの 4 行を書いておけば、以降のスタイリングで width の計算に悩むことはほぼなくなる。
width: 100% との関係
border-box が特に効果を発揮するのが width: 100% と padding を同時に使う場面だ。
親の幅いっぱい(100%)にさらに padding が加算されるため、親要素からはみ出してしまう。横スクロールが発生する典型的なパターンになる。
padding を含めて親の幅に収まるため、はみ出しが起きない。フォーム入力欄やカードコンポーネントで安心して使える。
/* content-box だとはみ出す */
input {
box-sizing: content-box;
width: 100%;
padding: 12px;
/* 実際の幅 = 親の100% + 24px → はみ出す */
}
/* border-box なら収まる */
input {
box-sizing: border-box;
width: 100%;
padding: 12px;
/* 実際の幅 = 親の100%(padding込み) */
}フォームの input や textarea は初期状態で content-box のブラウザもあるため、全称セレクタでのリセットが特に重要になる。border-box を前提にしたコーディングは、現代の CSS 開発における基本中の基本と言ってよい。