이 포스트는 CSS 레이아웃의 가장 근본적인 개념인 박스 모델(Box Model)에 대해 다루겠습니다.

웹 페이지의 모든 HTML 요소는 사각형 박스입니다. 이 박스가 어떻게 구성되고, 크기가 어떻게 계산되는지 알아보겠습니다.

브라우저는 모든 것을 박스로 본다

브라우저 렌더링 엔진은 HTML 요소를 화면에 그릴 때 모든 것을 직사각형 박스로 처리합니다. 텍스트든, 이미지든, 심지어 둥근 버튼이든 내부적으로는 모두 사각형 영역을 차지합니다.

/* 원처럼 보이지만 실제로는 정사각형 박스 */
.circle {
    width: 100px;
    height: 100px;
    border-radius: 50%; /* 시각적으로만 원 */
    background: red;
}

개발자 도구(F12)에서 요소를 선택하면 이 박스들이 색상으로 구분되어 표시됩니다. 이것이 바로 박스 모델의 시각화입니다.

박스 모델의 4개 레이어

모든 박스는 안쪽에서 바깥쪽으로 4개의 영역으로 구성됩니다:

1. Content (콘텐츠 영역)

실제 내용이 표시되는 영역입니다. 텍스트, 이미지, 비디오 등이 이곳에 위치합니다.

.box {
    width: 200px;   /* 콘텐츠 영역의 너비 */
    height: 100px;  /* 콘텐츠 영역의 높이 */
}

2. Padding (안쪽 여백)

콘텐츠와 테두리 사이의 간격입니다. 배경색이나 배경 이미지가 패딩 영역까지 확장됩니다.

.box {
    padding: 20px;              /* 모든 방향 20px */
    padding: 10px 20px;         /* 상하 10px, 좌우 20px */
    padding: 10px 20px 30px;    /* 상 10px, 좌우 20px, 하 30px */
    padding: 10px 20px 30px 40px; /* 상, 우, 하, 좌 (시계방향) */
    
    /* 개별 방향 */
    padding-top: 10px;
    padding-right: 20px;
    padding-bottom: 30px;
    padding-left: 40px;
}

3. Border (테두리)

요소를 감싸는 경계선입니다. 두께, 스타일, 색상을 지정할 수 있습니다.

.box {
    border: 2px solid #333;     /* 두께 스타일 색상 */
    
    /* 개별 설정 */
    border-width: 2px;
    border-style: solid;         /* solid, dashed, dotted, double 등 */
    border-color: #333;
    
    /* 방향별 설정 */
    border-top: 3px solid red;
    border-bottom: 1px dashed blue;
}

4. Margin (바깥 여백)

다른 요소와의 간격을 만드는 영역입니다. 투명하며 배경색이 적용되지 않습니다.

.box {
    margin: 20px;               /* 모든 방향 */
    margin: 0 auto;             /* 상하 0, 좌우 자동 (가운데 정렬) */
    margin: 10px 20px 30px 40px; /* 상, 우, 하, 좌 */
    
    /* 음수 마진도 가능 */
    margin-top: -10px;          /* 위로 당기기 */
}

box-sizing: 게임 체인저

box-sizing 속성은 widthheight가 어느 부분까지를 포함하는지 결정합니다. 이 하나의 속성이 CSS 레이아웃의 복잡성을 크게 줄여줍니다.

content-box (기본값): 전통적인 방식

.box {
    box-sizing: content-box;
    width: 200px;
    padding: 20px;
    border: 5px solid black;
}

/* 실제 차지하는 너비 = 200 + (20*2) + (5*2) = 250px */

content-box에서는 width가 순수 콘텐츠 영역만을 의미합니다. 패딩과 보더를 추가하면 요소의 전체 크기가 늘어납니다.

border-box: 현대적 표준

.box {
    box-sizing: border-box;
    width: 200px;
    padding: 20px;
    border: 5px solid black;
}

/* 실제 차지하는 너비 = 200px (패딩과 보더 포함) */
/* 콘텐츠 영역 = 200 - (20*2) - (5*2) = 150px */

border-box에서는 width가 보더까지 포함한 전체 크기를 의미합니다. 패딩이나 보더를 늘려도 전체 크기는 변하지 않고, 대신 콘텐츠 영역이 자동으로 줄어듭니다.

왜 border-box가 더 나은가?

단순한 계산으로 예측 가능한 레이아웃을 만들수 있습니다. 만약, content-box를 사용하면 컨텐츠 영역의 크기를 쉽게 예측하기 힘들어 컨테이너에 들어가 있는 요소들이 예상치 못하게 넘칠 수 있습니다.

/* content-box의 문제점 */
.container {
    width: 600px;
}

.column {
    box-sizing: content-box;
    width: 200px;
    padding: 20px;
    float: left;
}
/* 3개 컬럼 = (200 + 40) * 3 = 720px → 컨테이너 넘침! */

/* border-box의 해결책 */
.column {
    box-sizing: border-box;
    width: 200px;
    padding: 20px;
    float: left;
}
/* 3개 컬럼 = 200 * 3 = 600px → 완벽! */

전역 border-box 설정 (필수!)

모든 프로젝트에서 가장 먼저 추가해야 할 CSS입니다:

/* 모든 요소와 가상 요소에 적용 */
*,
*::before,
*::after {
    box-sizing: border-box;
}

/* 또는 상속을 활용한 방법 */
html {
    box-sizing: border-box;
}

*,
*::before,
*::after {
    box-sizing: inherit;
}

박스 크기 계산 완벽 정리

content-box 계산식

.element {
    box-sizing: content-box;
    width: 300px;
    height: 200px;
    padding: 20px;
    border: 5px solid black;
    margin: 10px;
}
총 너비 = margin-left + border-left + padding-left + width + padding-right + border-right + margin-right
        = 10 + 5 + 20 + 300 + 20 + 5 + 10
        = 370px
총 높이 = margin-top + border-top + padding-top + height + padding-bottom + border-bottom + margin-bottom
        = 10 + 5 + 20 + 200 + 20 + 5 + 10
        = 270px

요소가 차지하는 공간 (마진 포함) = 370px × 270px

요소의 시각적 크기 (마진 제외) = 350px × 250px

border-box 계산식

.element {
    box-sizing: border-box;
    width: 300px;
    height: 200px;
    padding: 20px;
    border: 5px solid black;
    margin: 10px;
}
총 너비 = margin-left + width + margin-right
        = 10 + 300 + 10
        = 320px
총 높이 = margin-top + height + margin-bottom
        = 10 + 200 + 10
        = 220px
콘텐츠 너비 = width - (border-left + padding-left + padding-right + border-right)
            = 300 - (5 + 20 + 20 + 5)
            = 250px
콘텐츠 높이 = height - (border-top + padding-top + padding-bottom + border-bottom)
            = 200 - (5 + 20 + 20 + 5)
            = 150px

박스 모델 베스트 프랙티스

1. 항상 border-box 사용

/* 모든 프로젝트의 첫 번째 규칙 */
*, *::before, *::after {
    box-sizing: border-box;
}

2. 일관된 간격 시스템

:root {
    --spacing-xs: 0.25rem;  /* 4px */
    --spacing-sm: 0.5rem;   /* 8px */
    --spacing-md: 1rem;     /* 16px */
    --spacing-lg: 1.5rem;   /* 24px */
    --spacing-xl: 2rem;     /* 32px */
    --spacing-2xl: 3rem;    /* 48px */
}

.component {
    padding: var(--spacing-md);
    margin-bottom: var(--spacing-lg);
}

3. 마진은 한 방향으로

/* 추천: 하단 마진만 사용 */
.element {
    margin-bottom: 1rem;
}

/* 마지막 요소 처리 */
.element:last-child {
    margin-bottom: 0;
}

/* 또는 인접 형제 선택자 활용 */
.element + .element {
    margin-top: 1rem;
}

4. 패딩으로 내부 간격, 마진으로 외부 간격

/* 명확한 역할 분리 */
.card {
    padding: 1.5rem;        /* 내부 콘텐츠 간격 */
    margin-bottom: 2rem;    /* 다른 카드와의 간격 */
}

5. 음수 마진 활용

/* 부모의 패딩 상쇄 */
.full-width-section {
    margin-left: -1rem;
    margin-right: -1rem;
}

/* 요소 겹치기 */
.overlap {
    margin-top: -2rem;
    z-index: 1;
}

정리

박스 모델은 CSS 레이아웃의 기초입니다. 이번 글에서 다룬 핵심 내용을 정리하면:

박스의 4개 영역:

  • Content → Padding → Border → Margin 순서
  • 각 영역의 역할과 특성 이해
  • 배경색은 패딩까지, 마진은 투명

box-sizing의 중요성:

  • content-box: 전통적이지만 계산이 복잡
  • border-box: 직관적이고 예측 가능
  • 모든 프로젝트에 border-box 전역 설정 필수

박스 모델을 정확히 이해하면 레이아웃 버그의 대부분을 쉽게 해결할 수 있습니다. 개발자 도구의 Computed 탭을 활용해서 박스 모델을 시각적으로 확인하는 습관을 들이면 더욱 빠르게 문제를 진단할 수 있습니다.


참고자료: