box-sizing は「width / height に padding と border を含めるか」を決めるプロパティです。実装では 原則 border-box にしつつ、コンテンツ最大幅を持つインナーコンテナだけ content-box に寄せる、という分け方には明確なメリットがあります。
content-box と border-box の違い(おさらい)
content-box(初期値)
width/heightは コンテンツ領域のみ。paddingとborderは その外側に加算される。border-box
width/heightは padding と border を含んだ枠までを指す(中身のコンテンツ領域は、指定幅から padding を引いた分になる)。
原則 border-box、例外は「インナーコンテナ」
案件では 全体を border-box にそろえることが多いです。リセット CSS で次のように * と疑似要素へ直接 border-box を指定している例もあります(コメントは意味の要約です)。
*,
::before,
::after {
box-sizing: border-box;
}
ここまでが前提のとき、.l-inner のように「インナー幅+左右ガター」を一つのクラスで表現するインナーコンテナだけ、content-box に切り替える判断がしばしば有効です。
なぜ max-width だけで済ませたいのか
border-box のまま 同一要素に max-width と padding-inline を両方載せると、max-width は border box の上限になります。つまり、見かけの コンテンツ幅は max-width から左右の padding を引いた値になります。
そのため、デザイン(Figma など)で与えられた 「インナー=コンテンツ幅」 をそのまま max-width に載せたい場合、次のどれかが必要になります。
max-width: calc(var(--inner) + var(--inner-padding) * 2);のように 数値を足す- インナーコンテナを二段に分け、内側だけに
max-width、外側だけに横 padding を載せる - その要素だけ
content-boxにし、max-width: var(--inner);のように インナー幅をそのまま書く
3 番目を選ぶと、デザイントークンと max-width を 1 対 1で結べるので、トークン運用やレビュー時の読み取りが楽になります。
width: 100% は付けない方がよいことが多い
.l-inner を次のように書く案があります。
.l-inner {
margin-inline: auto;
box-sizing: content-box;
max-width: var(--inner);
width: 100%;
padding-inline: var(--inner-padding);
}
box-sizing: content-box のとき、width: 100% は コンテンツ幅を親の幅いっぱいにします。padding-inline は その外側に加算されるため、親幅ぴったりに収めたい意図でも 100% + padding で横にはみ出しやすいです。
通常フローの ブロック要素であれば、**width を省略(既定の width: auto)**したままでも、多くの場合 親の利用可能幅に収まる振る舞いになり、margin-inline: auto と max-width とも相性が良いです。そのため .l-inner から width: 100% を外すのが無難です。
例外として、flex アイテムや grid アイテムとして min-width: auto 由来の縮み・はみ出しを抑える目的で width: 100% が入っていることはあり得ます。その場合は min-width: 0 など別解がないかもあわせて検討するとよいです。
リセット方式との注意(補足)
* { box-sizing: inherit; } のように inherit で揃える方式だと、親を content-box にしたとき 子孫へ伝播してしまうことがあります。一方、本稿冒頭のように 各要素へ border-box を直接指定するリセットであれば、子は引き続き border-box のままになりやすく、親のインナーコンテナだけ content-box にする運用と相性がよいです。
まとめ
- 全体は
border-boxでよい。width: 100%と padding の同居も扱いやすい。 - インナー幅+ガターを一要素で持つなら、そのインナーコンテナだけ
content-boxにしてmax-widthにインナー値を直書きできるようにする、は合理的な分割です。 - そのインナーコンテナがブロックなら、
width: 100%は外して100% + paddingの横溢出を避けるのが安全です。 border-boxのまま二層に分ける方法もあり、チームの好みと HTML の厚みで選べます。