브라우저는 모든 요소를 사각형 상자로 보고, 그 상자를 안쪽부터 콘텐츠(content) → 안쪽 여백(padding) → 테두리(border) → 바깥 여백(margin) 네 겹으로 계산한다. 레이아웃에서 요소가 차지하는 크기와 요소 사이 간격이 모두 이 네 겹에서 나온다.
margin
border
padding
content (width × height)box-sizing: width가 어디까지인가
| 값 | width가 가리키는 것 | 실제 차지 너비(margin 제외) |
|---|---|---|
content-box(기본값) | 콘텐츠만 | width + padding + border |
border-box | 콘텐츠 + padding + border | width 그대로 |
.card { width: 300px; padding: 20px; border: 1px solid; }
/* content-box: 342px, border-box: 300px */기본값으로는 padding을 늘리면 상자도 함께 커져서 계산이 번거롭다. 그래서 대부분의 CSS 리셋은 *, *::before, *::after { box-sizing: border-box; }로 시작한다.
알아 둘 동작
- 마진 상쇄(Margin Collapsing): 일반 흐름(normal flow)에서 위아래로 맞닿은 블록의 세로 margin은 더해지지 않고 큰 값 하나만 남는다. 부모와 첫·마지막 자식의 margin이 맞닿을 때, 내용 없는 빈 블록의 위아래 margin끼리도 상쇄된다. Flexbox·그리드(Grid) 아이템이거나 padding·border로 떨어져 있으면 생기지 않는다
- 인라인 상자:
display: inline이면width·height가 적용되지 않는다. 세로 margin은 효과가 없고, 세로 padding은 그려지기는 하지만 위아래 줄을 밀어내지 않는다.inline-block은 줄 안에 있으면서 블록처럼 크기를 받는다 - outline은 박스 밖:
outline과box-shadow는 크기 계산에 들어가지 않아 레이아웃을 흔들지 않는다 - 상자 크기가 바뀌면 리플로우(레이아웃 재계산)가 일어난다. DevTools Elements 패널의 Computed 탭에서 네 겹 수치를 그림으로 볼 수 있다 → 크롬 개발자 도구 팁
여러 규칙이 같은 박스 속성을 지정할 때 무엇이 이기는지는 CSS 캐스케이드와 CSS 명시도가 정한다.
명세: W3C — CSS Box Model Module Level 3 · W3C — CSS 2.2 §8.3.1 Collapsing margins · W3C — CSS 2.2 §10.6.1 Inline, non-replaced elements · W3C — CSS Box Sizing Module Level 3: box-sizing 출처: MDN — The box model · MDN — box-sizing · MDN — Mastering margin collapsing