CSS
박스 모델과 간격의 상쇄
선언한 크기에 포함되는 박스 영역과 박스 바깥의 간격 규칙을 나누어 계산합니다.
이럴 때 필요해요
너비를 100%로 주었는데 가로 스크롤이 생기거나 자식에게 준 위쪽 여백이 부모 바깥으로 튀어나오는 문제를 예방하기 위해 필요합니다.
어떻게 동작하나요?
너비를 20rem으로 맞춘 카드에 안쪽 여백(padding)과 테두리(border)를 넣었더니 카드가 예상보다 넓어져 줄바꿈이 깨지는 경우가 있습니다. 기본값인 box-sizing: content-box에서는 width가 순수 콘텐츠 영역의 너비만 뜻하기 때문입니다. 이를 box-sizing: border-box로 바꾸면 width 안에 콘텐츠뿐 아니라 padding과 border까지 함께 포함되어 외곽 크기를 일정하게 맞추기 쉽습니다. 단, 바깥 간격인 margin은 두 방식 모두 width 바깥에 별도로 놓입니다.
padding은 테두리 안쪽에서 콘텐츠 주변을 감싸는 여백이라 배경색과 클릭 영역이 함께 확장되며 음수 값을 쓸 수 없습니다. 반대로 margin은 테두리 바깥에서 이웃 요소와 거리를 벌리는 투명한 간격이며 음수 값을 주어 요소를 당기거나 겹치게 할 수도 있습니다. 버튼의 터치 영역을 넓히고 싶다면 margin이 아니라 padding을 키워야 하는 이유가 여기에 있습니다.
일반 블록 흐름에서는 위아래로 맞닿은 두 요소의 세로 margin이 각각 더해지지 않고 둘 중 더 큰 쪽 하나로 합쳐지는 '마진 상쇄(Margin Collapsing)'가 일어납니다. 특히 부모 박스에 padding이나 border 같은 경계가 없으면 첫 번째 자식의 margin-top이 부모 바깥으로 빠져나와 부모 자체가 아래로 밀려나기도 합니다. 이런 예측하기 어려운 상쇄를 피하려면 부모를 display: flex(또는 grid)로 만들고 gap 속성으로 자식 사이 간격을 관리하는 방식이 훨씬 직관적입니다.
코드 예제
동작을 설명하는 읽기 전용 예제입니다.
.card { box-sizing: border-box; width: 20rem; padding: 1rem; border: 1px solid; }
.stack { display: flex; flex-direction: column; gap: 1rem; }
.stack > * { margin: 0; }카드는 border-box를 사용해 테두리까지 포함한 외곽 너비를 20rem으로 고정하고, 세로 목록(.stack)은 자식의 margin 상쇄에 의존하는 대신 flex 컨테이너의 gap으로 일정한 1rem 간격을 유지합니다.
자주 헷갈리는 포인트
- box-sizing: border-box를 써도 테두리 바깥의 margin까지 width에 포함되지는 않습니다.
- 세로 margin이 어떤 배치에서나 항상 합산된다거나 반대로 언제나 상쇄된다고 단정하면 안 됩니다.
내 말로 설명해 보기
선언한 width 값이 똑같은 두 카드의 실제 가로 외곽 크기가 서로 다르다면 어떤 CSS 속성들을 비교해 보아야 할까요?
함께 읽으면 좋은 개념
관련 면접 질문 3개
CSS 박스 모델에서 margin과 padding은 각각 어떤 역할을 하나요?
padding은 콘텐츠와 테두리(border) 사이의 안쪽 여백이고, margin은 테두리 바깥에서 다른 요소와의 거리를 벌리는 바깥 간격입니다. 요소의 배경색이나 배경 이미지는 기본적으로 padding 영역까지 칠해지고 클릭 영역에도 포함되지만, margin 영역은 투명하게 비어 있어 배경이나 클릭 영역에 포함되지 않습니다. 또한 padding에는 음수 값을 줄 수 없지만 margin에는 음수 값을 주어 요소를 겹치거나 끌어당기는 배치가 가능합니다.
꼬리질문과 참고자료 →CSS 박스 모델의 구조와 box-sizing 속성의 차이를 설명해 주시겠어요?
CSS 박스 모델은 안쪽부터 콘텐츠(content), 안쪽 여백(padding), 테두리(border), 바깥 간격(margin)의 네 영역으로 구성됩니다. 기본값인 box-sizing: content-box에서는 선언한 width와 height가 순수 콘텐츠 영역의 크기만 뜻하므로, padding과 border를 더하면 실제 박스 외곽 크기가 그보다 커집니다. 반면 box-sizing: border-box를 지정하면 선언한 width와 height 안에 콘텐츠뿐 아니라 padding과 border까지 함께 포함되어 레이아웃 크기를 직관적으로 계산할 수 있습니다.
꼬리질문과 참고자료 →CSS에서 세로 margin 상쇄(Margin Collapsing)는 언제 일어나고 어떻게 피할 수 있나요?
세로 margin 상쇄는 일반 블록 흐름에서 위아래로 맞닿은 인접 형제나 경계가 없는 부모·자식의 세로 margin이 각각 더해지지 않고 하나로 합쳐지는 현상입니다. 양수끼리 만나면 더 큰 값이 남고 음수가 섞이면 계산이 달라져서 예상보다 간격이 줄어들거나 자식 여백이 부모 바깥으로 튀어나올 수 있습니다. 이를 피하려면 부모에 padding·border나 display: flow-root로 경계를 만들거나, Flexbox·Grid 컨테이너의 gap 속성으로 간격을 관리합니다.
꼬리질문과 참고자료 →