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은 일반적으로 병합되지 않습니다.
병합이 일어나는 대표 경우:
- 형제 요소: 위쪽 블록의
margin-bottom과 아래쪽 블록의margin-top - 부모와 첫·마지막 자식: 부모에 padding/border가 없고, 위 자식의
margin-top이 부모 밖으로 “튀어” 나가는 현상(겉보기 병합) - 빈 블록: 높이가 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으로 헤더 높이를 유지하고, main에 overflow: auto를 주면 뷰포트 높이 안에서 본문만 스크롤됩니다.
정리
핵심 요약
- Content: width, height
- Padding: 내부 여백
- Border: 테두리
- Margin: 외부 여백
- box-sizing: border-box 권장
- Display: block, inline, inline-block
박스 모델 디버깅 팁
- 개발자 도구에서 요소 선택 시 박스 모델 시각화
* { outline: 1px solid red; }로 모든 요소 확인box-sizing: border-box전역 적용 권장
다음 단계
- Flexbox 레이아웃
- Grid 레이아웃
- 반응형 웹 디자인
관련 글
- CSS Flexbox | 플렉스박스 레이아웃 완벽 가이드
- CSS Grid | 그리드 레이아웃 완벽 가이드
- C++ 메모리 정렬 |
- HTML/CSS 시작하기 | 웹 개발 첫걸음
- CSS 기초 | 선택자, 속성, 색상, 폰트