CSS를 배우다가 "왜 여기에 여백이 생기지?", "왜 크기가 내가 지정한 것보다 크지?"라는 경험이 한 번씩은 생긴다. 이 혼란의 대부분은 박스 모델을 모르기 때문이다.
HTML의 모든 요소는 눈에 보이지 않는 박스로 이루어져 있다. 이 박스는 네 가지 영역으로 구성된다.

div {
padding: 20px; /* 상하좌우 모두 20px */
padding: 10px 20px; /* 상하 10px, 좌우 20px */
padding: 10px 20px 15px; /* 상 10, 좌우 20, 하 15 */
padding: 10px 20px 15px 5px; /* 상 우 하 좌 (시계방향) */
}
/* 개별 지정 */
div {
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
padding-left: 20px;
}
padding은 배경색의 영향을 받는다. background-color를 지정하면 padding 영역까지 색이 채워진다.
div {
margin: 20px;
margin: 10px auto; /* 상하 10px, 좌우 auto → 가운데 정렬 */
margin: 0;
}
margin: 0 auto는 블록 요소를 가운데 정렬하는 고전적인 방법이다. 단, 요소에 width가 지정되어 있어야 한다.
인접한 블록 요소들의 마진이 합산되지 않고 더 큰 값 하나만 적용되는 현상이다.
.box1 { margin-bottom: 30px; }
.box2 { margin-top: 20px; }
/* 두 박스 사이 간격은 50px이 아니라 30px */
Flexbox나 Grid를 쓰면 마진 겹침이 발생하지 않는다.
div {
border: 1px solid #ccc; /* 두께 스타일 색상 */
border: 2px dashed red;
border: 3px dotted blue;
}
/* 개별 지정 */
div {
border-top: 2px solid black;
border-right: none;
border-radius: 8px; /* 모서리 둥글게 */
border-radius: 50%; /* 원형 */
}
border 스타일 종류: solid(실선), dashed(점선), dotted(점점선), double(이중선), none
width: 200px으로 지정한 요소가 실제로는 200px보다 크게 렌더링되는 경험이 있을 것이다. 기본값인 content-box 때문이다.
/* 기본값 — width가 content 영역만 포함 */
.box {
box-sizing: content-box;
width: 200px;
padding: 20px;
border: 5px solid black;
/* 실제 렌더링 너비: 200 + 20*2 + 5*2 = 250px */
}
/* border-box — width가 padding, border까지 포함 */
.box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 5px solid black;
/* 실제 렌더링 너비: 200px (지정값 그대로) */
}

그래서 대부분의 프로젝트에서 이걸 전역으로 설정하고 시작한다.
* {
box-sizing: border-box;
}
div {
width: 300px;
height: 200px;
max-width: 600px; /* 최대 너비 */
min-height: 100px; /* 최소 높이 */
width: 100%; /* 부모 너비의 100% */
}
박스 모델은 레이아웃의 기초다. padding과 margin의 차이, box-sizing: border-box의 동작 방식만 이해해도 크기와 여백 관련 문제의 절반은 해결된다.