CSS 박스 모델 | Margin, Padding, Border 완벽 정리

CSS 박스 모델 | Margin, Padding, Border 완벽 정리

이 글의 핵심

CSS 박스 모델에 대한 실전 가이드입니다. Margin, Padding, Border 완벽 정리 등을 예제와 함께 상세히 설명합니다.

들어가며

CSS 박스 모델은 모든 HTML 요소를 상자로 보는 관점입니다. 내용물(Content)은 상자 안 물건, padding은 완충재, border는 상자 테두리, margin은 상자 바깥의 간격이라고 이해하시면 레이아웃이 잡힙니다.

┌─────────────────────────────┐
│        Margin (외부)         │
│  ┌─────────────────────┐    │
│  │    Border (테두리)   │    │
│  │  ┌───────────────┐  │    │
│  │  │ Padding (내부)│  │    │
│  │  │  ┌─────────┐  │  │    │
│  │  │  │ Content │  │  │    │
│  │  │  └─────────┘  │  │    │
│  │  └───────────────┘  │    │
│  └─────────────────────┘    │
└─────────────────────────────┘

1. Content (내용)

.box {
    /* 너비와 높이 */
    width: 300px;
    height: 200px;
    
    /* 최소/최대 크기 */
    min-width: 200px;
    max-width: 500px;
    min-height: 100px;
    max-height: 400px;
}

2. Padding (내부 여백)

기본 사용

Padding은 요소의 내용과 테두리 사이의 여백입니다:

.box {
    /* 1. 모든 방향 동일 */
    padding: 20px;
    /* 상하좌우 모두 20px */
    
    /* 2. 상하 | 좌우 */
    padding: 10px 20px;
    /* 상하: 10px, 좌우: 20px */
    
    /* 3. 상 | 좌우 | 하 */
    padding: 10px 20px 30px;
    /* 상: 10px, 좌우: 20px, 하: 30px */
    
    /* 4. 상 | 우 | 하 | 좌 (시계방향) */
    padding: 10px 20px 30px 40px;
    /* 상: 10px, 우: 20px, 하: 30px, 좌: 40px */
    /* 시계방향: 12시 → 3시 → 6시 → 9시 */
}

시각적 설명:

/* padding: 10px 20px 30px 40px; */

        10px (top)

    ┌─────────────┐
40px│   Content   │20px (right)
(left)            │
    └─────────────┘

        30px (bottom)

실전 예시:

/* 버튼 패딩 */
.button {
    padding: 12px 24px;  /* 상하 12px, 좌우 24px */
    /* 버튼은 보통 좌우 여백이 더 넓음 */
}

/* 카드 패딩 */
.card {
    padding: 20px;  /* 모든 방향 동일 */
}

/* 헤더 패딩 */
.header {
    padding: 15px 30px;  /* 상하 15px, 좌우 30px */
}

개별 지정

.box {
    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;
    border-color: #333;
}

Border 스타일

.box {
    border-style: solid;   /* 실선 */
    border-style: dashed;  /* 점선 */
    border-style: dotted;  /* 점 */
    border-style: double;  /* 이중선 */
    border-style: groove;  /* 홈 */
    border-style: ridge;   /* 능선 */
    border-style: inset;   /* 안쪽 */
    border-style: outset;  /* 바깥쪽 */
}

개별 테두리

.box {
    border-top: 2px solid red;
    border-right: 3px dashed blue;
    border-bottom: 4px dotted green;
    border-left: 5px double orange;
}

Border Radius (둥근 모서리)

.box {
    /* 모든 모서리 */
    border-radius: 10px;
    
    /* 개별 모서리 */
    border-radius: 10px 20px 30px 40px;
    
    /* 원형 */
    border-radius: 50%;
    
    /* 타원형 */
    border-radius: 50% / 25%;
}

4. Margin (외부 여백)

기본 사용

.box {
    /* 모든 방향 동일 */
    margin: 20px;
    
    /* 상하 | 좌우 */
    margin: 10px 20px;
    
    /* 상 | 좌우 | 하 */
    margin: 10px 20px 30px;
    
    /* 상 | 우 | 하 | 좌 */
    margin: 10px 20px 30px 40px;
}

중앙 정렬

margin: auto를 사용하여 블록 요소를 가로 중앙에 배치할 수 있습니다:

.box {
    width: 300px;
    /* width가 지정되어야 함 (필수) */
    
    margin: 0 auto;
    /* 상하: 0, 좌우: auto */
    /* auto: 남은 공간을 자동으로 균등 분배 */
    /* 좌우 margin이 같아져서 중앙 정렬됨 */
}

/* 동작 원리:
   부모 컨테이너 1000px, 자식 300px일 때
   남은 공간: 1000px - 300px = 700px
   좌 margin: 700px / 2 = 350px
   우 margin: 700px / 2 = 350px
   결과: 자식이 중앙에 위치
*/

다양한 중앙 정렬 방법:

/* 1. 블록 요소 가로 중앙 (margin) */
.container {
    width: 800px;
    margin: 0 auto;  /* 가로 중앙 */
}

/* 2. 텍스트 중앙 (text-align) */
.text-center {
    text-align: center;  /* 인라인 요소 중앙 */
}

/* 3. Flexbox 중앙 (가로 + 세로) */
.flex-center {
    display: flex;
    justify-content: center;  /* 가로 중앙 */
    align-items: center;      /* 세로 중앙 */
}

/* 4. Grid 중앙 */
.grid-center {
    display: grid;
    place-items: center;  /* 가로 + 세로 중앙 */
}

/* 5. 절대 위치 중앙 */
.absolute-center {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

주의사항:

/* ❌ 작동 안 함: width 없음 */
.box {
    margin: 0 auto;  /* width가 없으면 효과 없음 */
}

/* ❌ 작동 안 함: 인라인 요소 */
span {
    width: 300px;
    margin: 0 auto;  /* 인라인 요소는 중앙 정렬 안 됨 */
}

/* ✅ 해결: display 변경 */
span {
    display: block;  /* 또는 inline-block */
    width: 300px;
    margin: 0 auto;
}

음수 Margin

.box {
    margin-top: -20px;
    margin-left: -10px;
}

Margin Collapse

.box1 {
    margin-bottom: 30px;
}

.box2 {
    margin-top: 20px;
}

/* 실제 간격: 30px (큰 값으로 합쳐짐) */

5. Box Sizing

content-box (기본값)

.box {
    box-sizing: content-box;
    width: 300px;
    padding: 20px;
    border: 5px solid;
    
    /* 실제 너비 = 300 + 40 + 10 = 350px */
}

border-box (권장)

.box {
    box-sizing: border-box;
    width: 300px;
    padding: 20px;
    border: 5px solid;
    
    /* 실제 너비 = 300px (padding, border 포함) */
}

/* 전체 적용 권장 */
* {
    box-sizing: border-box;
}

6. Display 속성

Block

.block {
    display: block;
    
    /* 특징 */
    /* - 한 줄 전체 차지 */
    /* - width, height 지정 가능 */
    /* - margin, padding 모두 적용 */
}

Inline

.inline {
    display: inline;
    
    /* 특징 */
    /* - 콘텐츠 크기만큼만 차지 */
    /* - width, height 무시 */
    /* - 상하 margin 무시 */
}

Inline-Block

.inline-block {
    display: inline-block;
    
    /* 특징 */
    /* - 한 줄에 여러 개 */
    /* - width, height 지정 가능 */
    /* - margin, padding 모두 적용 */
}

None

.hidden {
    display: none;  /* 완전히 숨김 */
}

.invisible {
    visibility: hidden;  /* 공간은 차지 */
}

7. Overflow

.box {
    width: 200px;
    height: 100px;
    
    /* 넘치는 내용 처리 */
    overflow: visible;  /* 기본값, 넘침 */
    overflow: hidden;   /* 숨김 */
    overflow: scroll;   /* 스크롤바 항상 표시 */
    overflow: auto;     /* 필요시 스크롤바 */
    
    /* 개별 지정 */
    overflow-x: hidden;
    overflow-y: auto;
}

8. 실전 예제

예제 1: 카드 UI

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>카드 UI</title>
    <style>
        * {
            box-sizing: border-box;
        }

        body {
            font-family: Arial, sans-serif;
            background: #f5f5f5;
            padding: 20px;
        }

        .card {
            width: 300px;
            background: white;
            border-radius: 10px;
            overflow: hidden;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin: 20px auto;
        }

        .card-image {
            width: 100%;
            height: 200px;
            background: #ddd;
        }

        .card-content {
            padding: 20px;
        }

        .card-title {
            margin: 0 0 10px 0;
            font-size: 24px;
        }

        .card-text {
            margin: 0 0 15px 0;
            color: #666;
            line-height: 1.6;
        }

        .card-button {
            display: inline-block;
            padding: 10px 20px;
            background: #3498db;
            color: white;
            text-decoration: none;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <div class="card">
        <div class="card-image"></div>
        <div class="card-content">
            <h2 class="card-title">카드 제목</h2>
            <p class="card-text">
                카드 내용입니다. 박스 모델을 활용하여 
                깔끔한 레이아웃을 만들 수 있습니다.
            </p>
            <a href="#" class="card-button">자세히 보기</a>
        </div>
    </div>
</body>
</html>

예제 2: 버튼 그룹

<style>
    .button-group {
        display: inline-block;
        border-radius: 5px;
        overflow: hidden;
    }

    .button-group button {
        display: inline-block;
        padding: 10px 20px;
        border: none;
        background: #3498db;
        color: white;
        cursor: pointer;
        margin: 0;
        border-right: 1px solid rgba(255,255,255,0.3);
    }

    .button-group button:last-child {
        border-right: none;
    }

    .button-group button:hover {
        background: #2980b9;
    }
</style>

<div class="button-group">
    <button>왼쪽</button>
    <button>중앙</button>
    <button>오른쪽</button>
</div>

예제 3: 프로필 카드

<style>
    .profile-card {
        width: 250px;
        background: white;
        border: 1px solid #ddd;
        border-radius: 8px;
        padding: 20px;
        text-align: center;
    }

    .profile-avatar {
        width: 80px;
        height: 80px;
        border-radius: 50%;
        background: #3498db;
        margin: 0 auto 15px;
    }

    .profile-name {
        margin: 0 0 5px 0;
        font-size: 20px;
        font-weight: bold;
    }

    .profile-role {
        margin: 0 0 15px 0;
        color: #666;
        font-size: 14px;
    }

    .profile-stats {
        display: flex;
        justify-content: space-around;
        padding-top: 15px;
        border-top: 1px solid #eee;
    }

    .stat {
        text-align: center;
    }

    .stat-value {
        display: block;
        font-size: 18px;
        font-weight: bold;
        margin-bottom: 5px;
    }

    .stat-label {
        font-size: 12px;
        color: #999;
    }
</style>

<div class="profile-card">
    <div class="profile-avatar"></div>
    <h3 class="profile-name">홍길동</h3>
    <p class="profile-role">Frontend Developer</p>
    <div class="profile-stats">
        <div class="stat">
            <span class="stat-value">42</span>
            <span class="stat-label">Posts</span>
        </div>
        <div class="stat">
            <span class="stat-value">1.2K</span>
            <span class="stat-label">Followers</span>
        </div>
        <div class="stat">
            <span class="stat-value">320</span>
            <span class="stat-label">Following</span>
        </div>
    </div>
</div>

9. box-sizing 심화: content-box vs border-box

이미 5. Box Sizing에서 두 값을 다뤘습니다. 실무에서는 아래만 기억하면 됩니다.

구분content-box (기본)border-box (권장)
width/height가 가리키는 영역콘텐츠 박스만padding + border까지 포함한 박스
width: 300px + padding: 20px실제 차지 너비 ≈ 300 + 좌우 padding + border보이는 너비가 300px (padding/border는 안쪽으로 들어감)
레이아웃 계산열 개수·퍼센트 맞출 때 실수하기 쉬움두 열 50% + padding 같은 패턴이 예측 가능

전역으로 border-box를 쓰는 이유: 픽셀 단위로 맞춘 카드·그리드에서 padding을 바꿔도 줄바꿈이 깨지지 않고, 미디어 쿼리 없이도 안정적인 너비를 유지하기 쉽습니다.

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

언제 content-box를 쓰나? 레거시 코드와 맞추거나, 디자인 도구에서 “콘텐츠 영역만” 픽셀로 고정해야 할 때 등 예외적으로만 씁니다.


10. 마진 병합(Margin Collapse) 완전 정리

인접한 수직 margin이 겹치면 더 큰 값 하나로 합쳐집니다. 좌우 margin은 일반적으로 병합되지 않습니다.

병합이 일어나는 대표 경우:

  1. 형제 요소: 위쪽 블록의 margin-bottom과 아래쪽 블록의 margin-top
  2. 부모와 첫·마지막 자식: 부모에 padding/border가 없고, 위 자식의 margin-top이 부모 밖으로 “튀어” 나가는 현상(겉보기 병합)
  3. 빈 블록: 높이가 0에 가까운 요소의 상하 margin

병합을 끊는 방법(실무):

  • 부모에 padding-top 또는 border 또는 overflow: hidden (또는 display: flow-root)을 주어 첫 자식 margin이 부모 안에 갇히게 하기
  • Flex/Grid 컨테이너의 직접 자식은 margin 병합 규칙이 달라져서, 레이아웃 래퍼로 자주 활용
  • 간격을 margin 대신 gap(flex/grid)으로 통일하면 병합 이슈를 피하기 쉬움
/* 형제 간 간격: margin 병합으로 의도와 다를 수 있음 */
.section + .section {
  margin-top: 3rem;
}

/* 한쪽만 쓰거나, 부모에 padding으로 통일하는 편이 예측 가능 */
.page {
  padding-block: 2rem;
}

11. Padding과 Margin — 선택 기준

목적이유
테두리·배경 안쪽 여백 (버튼 클릭 영역, 카드 내부)padding배경색·테두리와 함께 “한 덩어리”로 보이게
요소와 요소 사이 간격 (섹션 사이, 카드 사이)margin (또는 gap)시각적으로 “블록과 블록”의 거리
부모 안에서 자식 뭉치 간격gap (flex/grid)margin 병합 없이 균일한 간격

실무 팁:

  • 인터랙티브 요소(버튼, 링크): 터치 영역을 넓히려면 padding으로 잡는 경우가 많습니다.
  • 첫/마지막 요소 여백: 리스트·카드 묶음에서는 부모에 padding을 주고, 자식 margin을 최소화하면 예측이 쉽습니다.
  • 수평 간격만 필요하면 margin-inline을 쓰면 방향이 명확합니다.

12. 실전 레이아웃 패턴: 상단 고정 바 + 스크롤 영역

헤더는 고정하고 본문만 스크롤하는 패턴입니다. 박스 모델(border-box, padding)과 높이 계산이 함께 쓰입니다.

<style>
  * { box-sizing: border-box; }
  .app {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
  }
  .app-header {
    flex-shrink: 0;
    padding: 12px 20px;
    border-bottom: 1px solid #e0e0e0;
    background: #fff;
  }
  .app-main {
    flex: 1;
    padding: 20px;
    overflow: auto; /* 본문만 스크롤 */
  }
</style>

<div class="app">
  <header class="app-header">고정 헤더</header>
  <main class="app-main">
    <p>긴 콘텐츠…</p>
  </main>
</div>

flex-shrink: 0으로 헤더 높이를 유지하고, mainoverflow: auto를 주면 뷰포트 높이 안에서 본문만 스크롤됩니다.


정리

핵심 요약

  1. Content: width, height
  2. Padding: 내부 여백
  3. Border: 테두리
  4. Margin: 외부 여백
  5. box-sizing: border-box 권장
  6. Display: block, inline, inline-block

박스 모델 디버깅 팁

  • 개발자 도구에서 요소 선택 시 박스 모델 시각화
  • * { outline: 1px solid red; } 로 모든 요소 확인
  • box-sizing: border-box 전역 적용 권장

다음 단계

  • Flexbox 레이아웃
  • Grid 레이아웃
  • 반응형 웹 디자인

관련 글

  • CSS Flexbox | 플렉스박스 레이아웃 완벽 가이드
  • CSS Grid | 그리드 레이아웃 완벽 가이드
  • C++ 메모리 정렬 |
  • HTML/CSS 시작하기 | 웹 개발 첫걸음
  • CSS 기초 | 선택자, 속성, 색상, 폰트