3秒でわかる
CSSで指定した幅にpaddingとborderを含めるかを切り替えるプロパティ。レイアウトが1pxずつずれる原因を根本から消せます。
もう少し詳しく
どういうものか
box-sizing は、width と height で指定した数値が要素のどこまでを指すのかを決めるプロパティです。初期値の content-box では、指定した幅は文字や画像が入る中身の領域だけを指し、padding と border はその外側に足されます。border-box に変えると、指定した幅の内側に padding と border が収まり、見た目の外寸がそのまま指定値になります。
content-box width:200px + padding:20px×2 + border:1px×2 = 実際は242px
border-box width:200px の中に padding と border が入る = 実際も200pxなぜ必要か
要素を横に2つ並べて画面をちょうど半分ずつにしたい、という場面を考えます。content-box のままだと width: 50% に padding を足した瞬間に合計が100%を超え、2つ目が下へ落ちます。落ちないようにするには、幅の指定を calc(50% - 21px) のように border と padding を引いた式で書くことになり、余白を変えるたびに計算し直しが必要です。border-box にしておけば、余白をいくら変えても外寸は50%のまま動きません。
具体例
実務では、最初にページ全体へ一括で当ててしまうのが定番です。
*,
*::before,
*::after {
box-sizing: border-box;
}
.card {
width: 300px;
padding: 24px;
border: 2px solid #0071e3;
/* 画面上の幅はきっちり300px */
}*::before と *::after まで含めるのは、疑似要素は * の対象外で取りこぼすためです。
つまずきやすいところ
margin は border-box に含まれません。含まれるのは padding と border までで、margin は常に外側に足されます。「border-box にしたのに横幅がはみ出す」という相談のほとんどは margin が原因です。
もうひとつは継承の誤解です。box-sizing は自動的には継承されないので、親要素だけに書いても子には効きません。全体に効かせたいときは上のように * へ書くか、html { box-sizing: border-box } *, *::before, *::after { box-sizing: inherit } の形にします。
覚え方
content-box は中身の寸法、border-box は枠の外側までの寸法と覚えます。定規で箱を測るとき、中の空間を測るのか、箱そのものを測るのかの違いです。
