CSS에서 모든 HTML 요소는 하나의 사각형 박스로 취급됩니다. 이 박스가 어떻게 구성되어 있는지 이해하는 것이 레이아웃 작업의 출발점입니다. 박스 모델은 content, padding, border, margin이라는 네 가지 영역으로 이루어지며, 각 영역은 요소의 최종 크기와 주변 요소와의 관계를 결정합니다. 이 구조를 정확히 파악하지 못하면 요소의 크기가 예상과 다르게 나타나거나, 여백이 의도하지 않게 겹치거나 사라지는 문제가 반복적으로 발생합니다.
핵심 구성 요소
- 📦 Content 영역: 텍스트, 이미지 등 실제 내용이 들어가는 공간으로, width와 height 속성이 기본적으로 이 영역의 크기를 지정합니다
- Padding 영역: content와 border 사이의 안쪽 여백으로, 배경색이 적용되며 요소 내부의 여유 공간을 만들어 줍니다
- Border 영역: padding 바깥을 감싸는 테두리로, 굵기와 스타일을 지정할 수 있으며 요소의 전체 크기에 포함됩니다
- Margin 영역: border 바깥의 바깥쪽 여백으로, 다른 요소와의 간격을 만들며 배경색이 적용되지 않는 투명한 공간입니다
- 🔢 크기 계산: 기본적으로 요소의 실제 렌더링 너비는 content + padding + border를 모두 더한 값이 됩니다
실무에서의 영향
박스 모델을 제대로 이해하지 못하면 width: 200px로 설정한 요소가 실제 화면에서 260px로 렌더링되는 상황이 발생하며, 이는 레이아웃이 무너지는 가장 흔한 원인 중 하나입니다. 특히 여러 요소를 나란히 배치하는 그리드나 플렉스 레이아웃 작업에서 크기 계산 오류는 전체 구조를 망가뜨릴 수 있습니다. 또한 margin이 배경색을 갖지 않는다는 사실을 모르면, 요소 간 간격을 padding으로 처리하다가 배경 영역이 예상보다 넓어지는 실수를 하게 됩니다. 네 영역 각각의 역할과 크기에 미치는 영향을 명확히 구분하는 것이 이후에 배울 box-sizing 속성, 마진 겹침 현상 등 CSS의 다양한 동작 원리를 이해하는 기초가 됩니다.
핵심 개념
Content와 Padding 영역
입문
HTML 요소 안에는 실제 내용이 들어가는 공간과, 그 내용 주변에 숨 쉴 공간이 있어요. 이 두 가지가 무엇인지 일상 속 물건으로 이해해 봐요!
📦 Content 영역은 무엇인가요? Content 영역은 편지봉투 안에 들어있는 편지지라고 생각해보세요. 텍스트, 이미지 같은 실제 내용물이 자리 잡는 공간이에요. CSS에서 width와 height를 설정하면 기본적으로 이 편지지의 크기를 정하는 거예요.
🛋️ Padding 영역은 무엇인가요? Padding은 편지봉투 안쪽의 뽁뽁이 포장재예요. 편지지(content)와 봉투 가장자리(border) 사이에 있는 부드러운 완충 공간이죠. 이 공간에는 배경색이 들어가기 때문에, padding이 넓어지면 배경색 영역도 함께 넓어져요.
🎨 Padding이 있으면 무엇이 달라지나요? 버튼을 예로 들면, 글자 바로 옆에 테두리가 딱 붙어있으면 답답해 보이죠? padding을 주면 글자 주위에 여유 공간이 생겨서 훨씬 보기 좋아져요. 이 여유 공간에도 배경색이 그대로 칠해져서 버튼처럼 보이게 되는 거예요.
중급
Content 영역은 width와 height가 기본적으로 적용되는 공간으로, 실제 렌더링되는 텍스트나 이미지가 위치합니다. Padding은 content와 border 사이의 내부 여백으로, 요소의 background-color가 padding 영역까지 적용됩니다.
Padding의 배경색 적용 범위
background-color는 content + padding 전체 영역에 칠해집니다. 이 때문에 padding을 늘리면 배경색이 보이는 면적도 함께 넓어집니다. 반면 border 바깥(margin)은 항상 투명합니다.
.button {
padding: 12px 24px; /* 상하 12px, 좌우 24px */
background-color: blue;
/* 배경색은 content + padding 영역에 적용됨 */
}
.box {
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
padding-left: 20px;
}
padding 단축 속성 규칙
padding: 10px 20px 15px 5px는 상-우-하-좌 (시계 방향) 순서입니다. padding: 10px 20px은 상하 10px, 좌우 20px을 의미합니다.
심화
CSS 박스 모델에서 content 영역과 padding 영역은 W3C CSS Box Model Level 3 명세(CSS-BOX-3)에서 명확히 구분됩니다. 두 영역의 경계와 배경 렌더링 규칙은 명세의 background painting 알고리즘에 따라 결정됩니다.
W3C CSS Box Model Level 3 명세 기반 정의
W3C CSS-BOX-3, Section 8 (The CSS Box Model)에 따르면, content edge는 width/height 속성이 직접 적용되는 경계이며 content box를 형성합니다. padding edge는 content edge에서 padding 값만큼 확장된 경계로 padding box를 형성합니다.
CSS Backgrounds and Borders Level 3 명세(CSS-BACKGROUNDS-3), Section 2.1에 따르면, background-color와 background-image는 기본적으로 padding box까지 페인팅됩니다. 이 동작은 background-clip 속성으로 제어 가능하며, background-clip: content-box로 설정하면 content box 안에만 배경이 칠해집니다.
Blink 렌더링 엔진의 레이아웃 처리
Blink(Chrome/Edge)의 레이아웃 엔진에서 content 영역의 크기는 LayoutBox::ComputeContentLogicalWidth() 메서드를 통해 결정됩니다. padding 값은 LayoutBox::PaddingStart(), PaddingEnd() 등의 메서드로 논리적 방향(logical direction)에 따라 적용되며, 이는 writing-mode와 direction 속성에 의한 논리적 속성(logical property) 처리를 지원합니다.
padding 퍼센트 값의 특수 동작 CSS-BOX-3 명세에 따르면, padding에 퍼센트 값을 사용하면 상하 padding도 부모의 height가 아닌 부모의 width를 기준으로 계산됩니다. 이는 가로세로 비율이 고정된 요소(aspect-ratio box)를 만들 때 활용되는 명세 의도적 동작입니다.
Border와 Margin 영역
입문
박스의 바깥쪽에는 눈에 보이는 테두리와, 다른 박스와의 간격을 만드는 두 가지 영역이 있어요. 이것들이 어떻게 다른지 알아볼게요!
🖼️ Border는 어떤 영역인가요? Border는 액자의 틀이라고 생각해보세요. 그림(content + padding)을 감싸는 테두리예요. 실선, 점선, 굵게, 가늘게 등 다양한 스타일을 지정할 수 있고, 이 테두리의 두께도 요소의 전체 크기에 포함돼요.
📏 Margin은 어떤 영역인가요? Margin은 액자와 액자 사이의 벽 공간이에요. 투명한 바깥쪽 여백으로, 다른 요소들과 간격을 만들어 줘요. 중요한 점은, margin 부분에는 배경색이 칠해지지 않아요. 항상 투명하게 남아있어요.
🚨 Border와 Margin은 어떻게 다른가요? Border는 “요소 자신의 일부”이고, Margin은 “요소 바깥의 빈 공간”이에요. 배경색을 지정하면 border 안쪽까지는 색이 들어가지만, margin 영역은 절대 색이 칠해지지 않아요. 그래서 요소와 요소 사이의 간격을 만들 때 margin을 사용하는 거예요.
💡 언제 border를, 언제 margin을 사용하나요? 테두리 선을 보여주고 싶으면 border를 써요. 다른 요소와의 거리를 조절하고 싶으면 margin을 써요. 이 둘은 역할이 완전히 다르니 헷갈리지 않도록 해요!
중급
Border는 padding box를 감싸는 테두리 영역으로, border-width, border-style, border-color 세 속성으로 구성됩니다. Margin은 border 바깥의 외부 여백으로, background-color가 적용되지 않는 투명한 공간입니다.
Border가 크기에 미치는 영향
기본 박스 모델(box-sizing: content-box)에서 border-width는 요소의 전체 렌더링 크기에 더해집니다. width: 200px; border: 5px solid로 설정하면 실제 렌더링 너비는 210px(200 + 5 + 5)가 됩니다.
.card {
border: 2px solid #333; /* width style color 순서 */
border-radius: 8px; /* 모서리 둥글게 */
margin: 20px; /* 상하좌우 20px 외부 여백 */
}
.item + .item {
margin-top: 16px; /* 인접 요소 사이 간격 */
}
Margin의 투명성
Margin 영역은 항상 투명합니다. background-color를 설정해도 margin까지 칠해지지 않습니다. 이 때문에 요소 간 간격을 margin으로 처리하면 사이 공간이 깨끗하게 유지됩니다.
심화
Border와 margin은 W3C CSS Box Model Level 3 명세에서 서로 다른 painting 레이어와 레이아웃 참여 방식을 가집니다. 이 두 영역의 동작 차이를 명세 수준에서 이해하는 것이 레이아웃 예측 가능성을 높입니다.
W3C CSS-BOX-3 명세의 border box와 margin box 정의
CSS-BOX-3, Section 8.1에 따르면 border edge는 border 두께만큼 padding box를 확장한 경계입니다. border box는 border edge로 둘러싸인 영역으로, box-sizing: border-box 설정 시 width/height가 이 경계를 기준으로 계산됩니다.
margin edge는 border box를 margin 값만큼 확장한 가장 바깥 경계입니다. CSS Backgrounds and Borders Level 3 명세에 따르면 margin 영역은 background painting 범위에서 제외됩니다(background-clip 속성의 가장 넓은 범위인 border-box도 margin을 포함하지 않습니다).
outline과 border의 명세적 차이
border와 시각적으로 유사한 outline은 layout flow에 참여하지 않습니다. CSS Basic User Interface Level 4 명세에 따르면 outline은 border box 바깥에 그려지지만 공간을 차지하지 않아 주변 요소의 레이아웃에 영향을 주지 않습니다. 반면 border는 box model의 일부로 레이아웃 계산에 참여합니다.
Blink의 margin 처리와 Block Formatting Context
Blink 렌더링 엔진에서 margin은 LayoutBox::MarginBefore() 등의 메서드로 처리되며, Block Formatting Context(BFC) 내에서 마진 병합(margin collapsing) 알고리즘이 적용됩니다. CSS-BOX-3, Section 14에 따르면 인접한 블록 레벨 요소의 상하 margin은 더 큰 값 하나만 적용되는 병합 규칙을 따릅니다. 이는 margin이 “요소 간 거리를 보장하는 최솟값”처럼 동작하게 하는 설계 철학에서 비롯됩니다.
박스 크기 계산
입문
CSS에서 요소의 크기를 정할 때, 우리가 입력한 숫자가 최종 크기가 아닐 수 있어요! 어떻게 계산되는지 알아볼게요.
📐 width: 200px이면 실제 크기도 200px일까요? 아니에요! 기본 설정에서는 200px이 내용물(content)만의 크기예요. 여기에 padding과 border가 더해져서 실제 화면에서 보이는 크기가 결정돼요. 마치 선물 상자를 만들 때 내용물 크기 외에 포장지 두께와 리본 공간을 따로 계산해야 하는 것처럼요!
🧮 실제 크기는 어떻게 계산하나요? 실제 너비 = content 너비 + 왼쪽 padding + 오른쪽 padding + 왼쪽 border + 오른쪽 border예요. 예를 들어 content 200px, padding 좌우 각 10px, border 좌우 각 5px이면 실제 크기는 200 + 10 + 10 + 5 + 5 = 230px이 돼요.
🚨 이게 왜 문제가 되나요? 여러 박스를 나란히 놓을 때 문제가 생겨요. 각각 width: 50%로 설정했는데 padding이나 border가 있으면, 실제 크기는 50%보다 커져서 두 박스가 나란히 들어가지 않고 밀려나게 돼요. 이런 계산 실수가 레이아웃이 무너지는 가장 흔한 이유예요!
💡 Margin은 크기에 포함되나요? Margin은 요소 자체의 크기에는 포함되지 않아요. Margin은 요소 바깥의 공간이라서, 다른 요소와의 간격을 만들기는 하지만 그 요소의 박스 크기를 키우지는 않아요.
중급
CSS 기본 박스 모델(box-sizing: content-box)에서 width와 height는 content 영역만의 크기를 지정합니다. 요소의 실제 렌더링 크기는 content + padding + border의 합산값입니다. Margin은 레이아웃 공간을 차지하지만 요소 박스 자체의 크기에는 포함되지 않습니다.
크기 계산 공식
- 렌더링 너비 = content width + padding-left + padding-right + border-left-width + border-right-width
- 렌더링 높이 = content height + padding-top + padding-bottom + border-top-width + border-bottom-width
.box {
width: 200px;
padding: 10px; /* 상하좌우 10px */
border: 5px solid; /* 상하좌우 5px */
/* 실제 렌더링 너비: 200 + 10 + 10 + 5 + 5 = 230px */
/* 실제 렌더링 높이: height 미설정 + 10 + 10 + 5 + 5 = auto + 30px */
}
box-sizing으로 계산 방식 변경
box-sizing: border-box로 설정하면 width가 content + padding + border를 포함한 전체 크기를 의미하게 됩니다. 현대 CSS 작업에서는 * { box-sizing: border-box; }를 전역 설정으로 사용하는 것이 일반적입니다.
/* content-box (기본): width가 content만의 크기 */
.default {
box-sizing: content-box;
width: 200px;
padding: 10px;
border: 5px solid;
/* 실제 너비: 230px */
}
/* border-box: width가 전체 크기 */
.modern {
box-sizing: border-box;
width: 200px;
padding: 10px;
border: 5px solid;
/* 실제 너비: 200px (content는 170px) */
}
심화
CSS 박스 크기 계산은 W3C CSS Box Model Level 3 명세의 used value 결정 알고리즘과 CSS Sizing Level 3 명세의 intrinsic/extrinsic sizing 개념이 복합적으로 적용됩니다. 기본 content-box 모델의 크기 계산은 명세 설계 철학의 산물이며, border-box와의 차이는 단순한 편의성 이상의 명세적 의미를 갖습니다.
W3C CSS-BOX-3 명세의 used value 계산
CSS-BOX-3, Section 8과 CSS2.1 Section 10에 따르면, 블록 레벨 요소의 너비 계산은 다음 순서로 이루어집니다: (1) width computed value 결정, (2) padding과 border의 used value 결정, (3) margin 처리(auto 값 해석 포함). 이때 width: auto는 available space에서 margin, border, padding을 뺀 값으로 결정됩니다(shrink-to-fit의 경우 다르게 계산).
content-box와 border-box의 명세적 차이
CSS Box Sizing Level 3, Section 1.2에 따르면 box-sizing 속성은 width와 height가 참조하는 box를 결정합니다. content-box는 CSS2.1의 원래 동작이며, border-box는 Internet Explorer의 쿼크 모드 동작을 표준화한 것입니다. border-box에서 content 영역의 실제 크기는 max(0, width - padding-left - padding-right - border-left-width - border-right-width)로 계산됩니다.
Blink의 크기 계산 파이프라인
Blink 렌더링 엔진의 레이아웃 단계에서 박스 크기 계산은 NGBlockLayoutAlgorithm(새 레이아웃 엔진 LayoutNG 기준)을 통해 처리됩니다. ComputeMinMaxSizes() 메서드가 min-content/max-content 사이즈를 계산하고, Layout() 메서드가 containing block의 가용 공간을 기반으로 final used size를 결정합니다. 이 과정에서 subpixel rendering을 위해 LayoutUnit(1/64px 단위 고정소수점)으로 내부 계산이 이루어집니다.
크기 계산과 스태킹 컨텍스트의 관계
박스의 크기 계산 결과는 paint 단계의 stacking context 형성에도 영향을 줍니다. CSS-BOX-3 명세에 따르면 margin box는 레이아웃 공간을 차지하지만 painting 대상이 아니므로, 크기 계산 시 margin을 포함하는 것과 포함하지 않는 것의 구분이 offsetWidth/scrollWidth 등 DOM API의 반환값 차이로 나타납니다.