CSS 강좌 / 안쪽 여백(padding)과 바깥 여백(margin)

CSS의 padding은 내용과 테두리 사이의 안쪽 여백이고, margin은 테두리 바깥의 여백입니다. 배경색을 포함한 요소 내부를 넓히려면 padding을, 주변 요소와의 거리를 조절하려면 margin을 사용합니다. 실제 너비는 box-sizing에 따라 달라지며, 세로 margin은 조건에 따라 겹쳐 단순히 더한 값과 달라질 수 있습니다.

padding과 margin의 차이

요소의 상자는 내용(content), 안쪽 여백(padding), 테두리(border), 바깥 여백(margin) 순서로 구성됩니다. 일반적인 배경색은 padding 영역까지 칠해지지만 margin은 투명합니다. 버튼의 padding을 늘리면 보통 배경과 클릭할 수 있는 상자도 커지지만, margin으로 만든 바깥 간격이 클릭 영역이 되지는 않습니다.

구분 padding margin
위치 내용과 테두리 사이 테두리 바깥
일반적인 배경색 padding 영역에도 표시 투명
음수 값 허용하지 않음 허용
auto 값 허용하지 않음 허용하되 배치 조건에 따라 계산

padding과 margin 모두 px, rem, % 같은 값을 사용할 수 있지만 padding: auto나 음수 padding은 유효하지 않습니다. 일반적인 가로쓰기 상자에서 물리 방향의 퍼센트 여백은 위·아래 값까지도 기준이 되는 포함 블록의 너비를 참조하므로, 높이의 일정 비율이라고 생각하면 안 됩니다. W3C 박스 모델과 여백 정의

1개부터 4개까지 값의 방향 읽기

축약형은 위쪽에서 시작해 오른쪽·아래쪽·왼쪽 순으로 읽습니다. 두 값이면 위아래와 좌우, 세 값이면 위·좌우·아래입니다. 다음 규칙은 padding과 margin에 똑같이 적용됩니다.

예시 위 오른쪽 아래 왼쪽
padding: 10px 10px 10px 10px 10px
padding: 10px 20px 10px 20px 10px 20px
padding: 10px 20px 30px 10px 20px 30px 20px
padding: 10px 20px 30px 40px 10px 20px 30px 40px

한 방향만 바꾸려면 padding-top, margin-left처럼 방향이 붙은 속성을 씁니다. 나중에 작성한 padding이나 margin 축약형이 앞서 지정한 개별 방향 값을 다시 덮어쓸 수 있으므로 규칙의 순서도 확인하세요.

전체 예제로 실제 너비 확인하기

아래 코드를 UTF-8 형식의 spacing.html로 저장한 뒤 브라우저에서 엽니다. 별도 라이브러리나 서버는 필요하지 않습니다. 예제의 Alpha·Beta 등은 비교용 표시입니다. 파일을 수정하면 저장하고 새로고침하세요. 개발자 도구에서 각 .box를 선택하고 박스 모델 그림이나 계산된 스타일로 너비와 여백을 확인합니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>padding과 margin 비교</title>
  <style>
    body { font-family: sans-serif; max-width: 640px; margin: 0 auto; padding: 16px; }
    h2 { font-size: 1.1rem; }
    .stage { padding: 12px; border: 1px dashed #777; overflow-x: auto; }
    .box { width: 200px; padding: 16px; border: 4px solid #17324d; margin: 24px; background: #dcefff; }
    .content-box { box-sizing: content-box; }
    .border-box { box-sizing: border-box; }
    .asymmetric { box-sizing: border-box; padding: 8px 16px 24px 32px; margin: 10px 20px 30px 40px; }
    .center { box-sizing: border-box; margin: 0 auto; }
    .collapse-demo { display: flow-root; border: 1px dashed #777; }
    .item { height: 30px; background: #dcefff; }
    .first { margin: 0 0 24px; }
    .second { margin: 16px 0 0; }
  </style>
</head>
<body>
  <h1>padding과 margin 비교</h1>
  <h2>content-box</h2>
  <div class="stage"><div class="box content-box">Alpha</div></div>
  <h2>border-box</h2>
  <div class="stage"><div class="box border-box">Beta</div></div>
  <h2>padding / margin</h2>
  <div class="stage"><div class="box asymmetric">Gamma</div></div>
  <h2>margin: 0 auto</h2>
  <div class="stage"><div class="box center">Delta</div></div>
  <h2>margin-bottom / margin-top</h2>
  <div class="collapse-demo">
    <div class="item first">A</div>
    <div class="item second">B</div>
  </div>
</body>
</html>

Alpha 상자의 테두리를 포함한 너비는 200 + 16 × 2 + 4 × 2 = 240px입니다. 좌우 margin까지 합친 가로 공간은 240 + 24 × 2 = 288px입니다. Beta는 border-box이므로 테두리까지 200px이고, 내용 너비는 200 - 16 × 2 - 4 × 2 = 160px입니다. 이 계산에는 바깥 stage 요소의 padding과 border를 넣지 않습니다.

Gamma는 padding이 위 8px·오른쪽 16px·아래 24px·왼쪽 32px로 다르게 보입니다. margin은 위 10px·오른쪽 20px·아래 30px·왼쪽 40px입니다. 위에서 다룬 축약형의 방향과 실제 화면을 대조해 보세요.

box-sizing으로 크기 계산 기준 정하기

content-box에서는 width가 내용 너비를 뜻하므로 padding과 border가 그 바깥에 더해집니다. border-box에서는 width 안에 내용·padding·border를 포함하며 margin은 어느 방식에서도 width에 포함하지 않습니다. 일반적인 div의 초기 계산 방식은 content-box이지만 사이트의 초기화 CSS가 바꿀 수 있으므로 실제 계산된 값을 확인해야 합니다.

실습 파일의 .content-box 규칙을 아래처럼 바꾸면 Alpha의 테두리 포함 너비가 240px에서 200px로 줄어듭니다. 다른 값은 그대로 두고 비교한 뒤 content-box로 되돌리세요. padding과 border의 합이 지정한 너비보다 지나치게 크면 내용 너비를 음수로 만들 수 없으므로 기대한 너비보다 커질 수도 있습니다.

.content-box {
  box-sizing: border-box;
}

MDN의 box-sizing 설명

margin: auto로 가운데 정렬하기

일반적인 문서 흐름에 있는 블록 상자를 가로 가운데에 놓으려면 상자가 부모의 사용 가능한 너비보다 좁아야 하며, 좌우 margin을 auto로 지정합니다. 실습의 Delta는 width 200px에 margin: 0 auto를 적용해 남는 가로 공간을 양쪽에 나누어 둡니다. 부모가 너무 좁으면 가운데 정렬만으로 넘침을 해결할 수 없습니다.

width가 auto인 일반 블록이 이미 가로 공간을 채우고 있다면 좌우 auto margin만 넣어도 눈에 띄는 변화가 없습니다. 또 일반 흐름의 margin-top: auto와 margin-bottom: auto가 세로 가운데 정렬을 만드는 것은 아닙니다. Flexbox나 Grid의 auto margin은 다른 배치 규칙을 따르므로 그 문맥과 구분하세요.

세로 margin 겹침과 음수 값 주의하기

일반 블록 흐름에서 조건에 맞는 인접한 세로 margin은 하나로 겹칠 수 있습니다. 실습 마지막 A의 아래 margin 24px과 B의 위 margin 16px은 둘 다 양수이므로 간격이 40px이 아니라 큰 값인 24px이 됩니다. 이 예제에서는 부모의 border가 자식과 부모 사이의 margin 겹침을 막습니다.

실습 파일에서 .collapse-demo 규칙을 아래처럼 바꾸면 자식이 Flexbox 항목이 되어 서로의 margin이 겹치지 않고 간격이 24 + 16 = 40px이 됩니다. 비교 후 display: flow-root로 되돌리세요. 부모에 flow-root를 주는 것만으로 형제 블록 사이의 margin 겹침까지 모두 사라지는 것은 아닙니다.

.collapse-demo {
  display: flex;
  flex-direction: column;
  border: 1px dashed #777;
}

이 예제처럼 일반적인 가로쓰기에서는 좌우 margin이 이런 방식으로 겹치지 않습니다. 겹치는 세로 margin에 양수와 음수가 섞이면 가장 큰 양수와 절댓값이 가장 큰 음수를 더합니다. 예를 들어 24px과 -8px이면 16px입니다. 모두 음수라면 절댓값이 가장 큰 음수를 사용하므로 -8px과 -16px은 -16px이 됩니다. margin-left: -8px 같은 음수 값은 유효하지만 내용이 겹치거나 부모 밖으로 나갈 수 있으므로 좁은 화면과 키보드 초점 표시도 확인하세요. 음수 padding으로 같은 효과를 만들 수는 없습니다. W3C의 margin 겹침 규칙

예상대로 적용되지 않을 때 확인할 사항

  1. 브라우저 기본 여백을 확인합니다. body의 기본 margin, p·h1 등의 기본 위아래 margin 때문에 작성한 값보다 간격이 커 보일 수 있습니다. 필요한 요소만 선택해 초기화하고 모든 여백을 무조건 지우지 마세요.
  2. 일반적인 비대체 인라인 요소인 span은 위아래 margin이 줄 배치에 영향을 주지 않습니다. 인라인 padding은 그려져도 줄 간격을 기대처럼 밀어내지 않을 수 있습니다. 상자의 높이·여백을 독립적으로 다뤄야 한다면 inline-block 또는 다른 배치 방식을 검토합니다.
  3. 개발자 도구에서 선택자가 맞는지, 선언이 유효한지, 더 높은 우선순위나 뒤쪽 축약형에 덮였는지 확인합니다. 좁은 창에서도 내용이 넘치지 않는지, padding을 바꿀 때 너비가 예상대로 변하는지 비교합니다.

쓰기 방향에 따라 여백을 지정하려면 padding-inline, margin-block 같은 논리 속성도 사용할 수 있습니다. 일반적인 가로쓰기에서 inline은 가로 축, block은 세로 축이지만 세로쓰기에서는 달라지므로 물리 방향의 left·right와 항상 같다고 생각하지 마세요.