현록

CSS margin과 padding 차이

CSS로 간격을 만들 때 가장 먼저 만나는 속성이 marginpadding이다.
둘 다 요소 주변에 빈 공간을 만들지만, 공간이 생기는 위치와 요소 크기에 미치는 영향은 다르다.

가장 짧게 구분하면 margin은 테두리 바깥쪽 간격이고, padding은 콘텐츠와 테두리 사이의 안쪽 간격이다.
요소끼리 떨어뜨릴 때는 margin, 요소 안에서 콘텐츠에 여유를 줄 때는 padding을 먼저 생각하면 된다.

CSS 박스 모델의 구조

브라우저는 대부분의 HTML 요소를 사각형 박스로 계산한다.
이 구조를 CSS 박스 모델이라고 부른다.

박스는 안쪽부터 다음 순서로 구성된다.

  1. content: 글자나 이미지가 놓이는 영역
  2. padding: 콘텐츠와 테두리 사이의 공간
  3. border: 요소의 테두리
  4. margin: 테두리 바깥의 공간
.card {
  width: 240px;
  padding: 20px;
  border: 1px solid #d8dee4;
  margin: 24px;
}

위 코드에서 padding: 20px은 카드 안의 콘텐츠를 테두리에서 떨어뜨린다.
margin: 24px은 카드 자체를 주변 요소와 떨어뜨린다.

이 구조를 이해하면 두 속성을 외우지 않아도 선택할 수 있다.
테두리를 기준으로 안쪽이면 padding, 바깥쪽이면 margin이다.

margin의 역할

margin은 요소의 border 바깥에 공간을 만든다.
형제 요소 사이의 거리나 섹션 사이의 간격을 조정할 때 주로 사용한다.

<section class="section">첫 번째 섹션</section>
<section class="section">두 번째 섹션</section>
.section {
  margin-bottom: 32px;
}

첫 번째 섹션의 테두리 바깥 아래쪽에 32px 공간이 생긴다.
이 공간은 요소 내부가 아니므로 섹션의 배경색으로 칠해지지 않는다.

margin에는 auto를 사용할 수 있다.
가로 크기가 정해진 block 요소를 가운데 정렬할 때 margin-inline: auto 또는 margin: 0 auto를 자주 쓴다.

.content {
  width: min(100% - 32px, 720px);
  margin-inline: auto;
}

margin에는 음수도 지정할 수 있다.
다만 요소를 겹치거나 기존 흐름을 당기는 효과가 생겨 레이아웃을 읽기 어려워질 수 있으므로, 명확한 의도가 있을 때만 사용하는 편이 좋다.

padding의 역할

padding은 콘텐츠와 border 사이에 공간을 만든다.
카드 안쪽 여백, 버튼의 클릭 영역, 입력창 안쪽 간격처럼 요소 내부의 여유를 만들 때 사용한다.

<button class="save-button" type="button">저장</button>
.save-button {
  padding: 10px 16px;
  border: 0;
  border-radius: 4px;
  background: #1769e0;
  color: #fff;
}

버튼 글자 주변에 padding이 생기면서 버튼 자체의 크기도 커진다.
이 영역은 버튼에 포함되므로 배경색이 칠해지고 클릭할 수 있는 범위에도 포함된다.

padding에는 음수를 사용할 수 없다.
콘텐츠와 border 사이의 공간은 0보다 작아질 수 없기 때문이다.

margin과 padding의 핵심 차이

두 속성은 다음 기준으로 구분할 수 있다.

  • 공간의 위치: margin은 border 바깥이고 padding은 border 안쪽이다.
  • 배경색: margin 영역은 항상 투명하고 padding 영역에는 기본적으로 요소의 배경이 보인다.
  • 클릭 영역: margin은 클릭 영역에 포함되지 않고 padding은 포함된다.
  • 요소 크기: padding은 요소가 차지하는 박스 크기를 늘릴 수 있지만 margin은 박스 바깥 간격으로 계산된다.
  • 사용 가능한 값: marginauto와 음수를 사용할 수 있지만 padding은 둘 다 사용할 수 없다.
  • 세로 간격 합치기: block 요소의 인접한 위아래 margin은 합쳐질 수 있지만 padding은 합쳐지지 않는다.

카드 안의 글자가 테두리에 너무 붙어 있다면 padding을 사용한다.
카드와 다음 카드가 너무 붙어 있다면 margin을 사용한다.

배경색과 클릭 영역의 차이

배경색을 주면 두 속성의 차이를 눈으로 확인하기 쉽다.

<a class="link" href="/">홈으로 이동</a>
.link {
  display: inline-block;
  margin: 20px;
  padding: 12px 16px;
  background: #ffe3d8;
}

배경색은 글자와 padding 영역을 감싼다.
바깥쪽의 margin: 20px 영역에는 배경색이 칠해지지 않는다.

링크를 클릭할 수 있는 범위도 글자와 padding 영역까지다.
터치하기 쉬운 버튼을 만들고 싶다면 margin으로 주변만 벌리는 것보다 적절한 padding으로 요소 자체의 크기를 확보해야 한다.

예제에서 링크에 display: inline-block을 준 이유는 크기와 위아래 여백을 박스처럼 다루기 위해서다.
요소의 바깥 배치 방식이 헷갈린다면 CSS display block inline inline-block 차이를 함께 보면 연결해서 이해하기 쉽다.

요소 전체 크기와 box-sizing

기본 box-sizing 값은 content-box다.
이 상태에서 width는 content 영역의 너비만 뜻한다.

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

이 요소가 실제로 차지하는 border 바깥쪽 너비는 244px이다.
content 200px에 좌우 padding 40px과 좌우 border 4px이 더해진다.
margin은 이 244px 박스 바깥에 별도의 간격을 만든다.

너비 안에 padding과 border를 포함하고 싶다면 border-box를 사용한다.

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

.box {
  width: 200px;
  padding: 20px;
  border: 2px solid;
}

이제 .box의 border 바깥쪽 너비는 지정한 200px 안에서 계산된다.
margin은 여전히 그 너비에 포함되지 않는다.

레이아웃 너비가 예상보다 커졌다면 padding 자체보다 먼저 box-sizing이 무엇인지 확인하는 편이 빠르다.

축약형 작성 순서

marginpadding은 한 줄에 1개부터 4개까지 값을 쓸 수 있다.
두 속성의 해석 순서는 같다.

값이 하나면 네 방향 모두에 적용된다.

.box {
  margin: 16px;
  padding: 12px;
}

값이 두 개면 첫 번째는 위아래, 두 번째는 좌우다.

.box {
  margin: 24px 16px;
  padding: 12px 20px;
}

값이 세 개면 위, 좌우, 아래 순서다.

.box {
  margin: 24px 16px 32px;
}

값이 네 개면 위에서 시작해 시계 방향으로 읽는다.

.box {
  margin: 8px 16px 24px 32px;
  padding: 4px 8px 12px 16px;
}

순서는 top, right, bottom, left다.
처음에는 네 값을 한꺼번에 외우기보다 위에서 시작해 시계 방향으로 돈다고 기억하면 편하다.

방향별 속성과 논리 속성

한쪽 간격만 바꾸고 싶다면 방향별 속성을 사용할 수 있다.

.box {
  margin-top: 24px;
  margin-right: 16px;
  margin-bottom: 32px;
  margin-left: 16px;

  padding-top: 12px;
  padding-right: 20px;
  padding-bottom: 12px;
  padding-left: 20px;
}

현대 CSS에서는 문서의 쓰기 방향을 고려한 논리 속성도 사용할 수 있다.

.article {
  margin-block: 32px;
  padding-inline: 20px;
}

가로쓰기 문서에서 margin-block은 주로 위아래 간격을 뜻한다.
padding-inline은 주로 좌우 안쪽 간격을 뜻한다.
다국어 레이아웃을 고려한다면 물리 방향인 left, right보다 논리 방향인 inline, block이 의도를 더 잘 드러낼 수 있다.

margin auto 가운데 정렬

margin: 0 auto는 block 요소를 가로 방향 가운데에 놓을 때 자주 사용한다.

.article {
  width: min(100% - 32px, 720px);
  margin: 0 auto;
}

좌우 auto margin이 부모 안의 남는 공간을 나눠 가진다.
요소가 부모 너비를 이미 전부 차지하고 있다면 나눌 남는 공간이 없으므로 가운데 정렬 효과가 눈에 보이지 않는다.

버튼 안의 글자를 가운데 정렬하는 용도로 margin: auto를 쓰는 것은 목적이 다르다.
텍스트 정렬은 text-align, flex item 정렬은 justify-contentalign-items처럼 해당 레이아웃 방식에 맞는 속성을 사용해야 한다.

margin collapsing

일반 block 레이아웃에서는 인접한 세로 margin이 서로 합쳐질 수 있다.
이를 margin collapsing 또는 마진 상쇄라고 부른다.

<div class="first">첫 번째</div>
<div class="second">두 번째</div>
.first {
  margin-bottom: 24px;
}

.second {
  margin-top: 16px;
}

두 요소 사이의 간격이 항상 24px + 16px = 40px이 되는 것은 아니다.
두 margin이 맞닿는 조건에서는 더 큰 값인 24px로 합쳐질 수 있다.

이 동작은 주로 일반 block 흐름의 위아래 margin에서 발생한다.
flex item과 grid item의 margin은 이런 방식으로 합쳐지지 않는다.
좌우 margin도 margin collapsing 대상이 아니다.

목록처럼 반복되는 요소의 간격을 일정하게 관리한다면 부모의 gap을 사용하는 방법도 있다.

.card-list {
  display: grid;
  gap: 24px;
}

gap은 항목 사이 간격을 부모에서 한 번에 관리하므로 첫 항목과 마지막 항목의 바깥 여백을 따로 제거할 필요가 없다.

실전 선택 기준

카드 안쪽의 글자와 테두리 사이를 벌릴 때는 padding을 사용한다.

.card {
  padding: 24px;
  border: 1px solid #d8dee4;
}

페이지 본문을 화면 가장자리에서 떨어뜨릴 때도 보통 컨테이너의 padding이 자연스럽다.

.page {
  padding-inline: 20px;
}

서로 다른 섹션 사이의 바깥 간격에는 margin을 사용할 수 있다.

.hero {
  margin-bottom: 64px;
}

반복되는 카드나 버튼 사이의 간격에는 부모의 gap이 더 관리하기 쉬운 경우가 많다.

.actions {
  display: flex;
  gap: 12px;
}

요소를 다른 요소 위에 겹쳐 놓는 문제라면 margin보다 위치 지정 방식부터 확인해야 한다.
CSS position relative와 absolute 차이에서 기준 요소와 배치 흐름을 함께 정리했다.

자주 생기는 실수

버튼을 크게 만들려고 margin을 늘리면 버튼 주변 공간만 커진다.
배경색과 클릭 영역까지 키우려면 padding을 늘려야 한다.

고정 너비 요소에 padding을 추가한 뒤 화면을 벗어난다면 box-sizing: border-box 적용 여부를 확인한다.

위아래 margin을 더했는데 예상보다 간격이 작다면 margin collapsing이 발생했는지 확인한다.

span 같은 inline 요소에 위아래 margin을 줬는데 주변 줄이 밀리지 않는다면 요소의 display 값을 확인한다.

반복 요소마다 margin-right를 주고 마지막 요소만 예외 처리하고 있다면 부모의 gap으로 단순화할 수 있는지 살펴본다.

정리

margin은 border 바깥의 간격이다.
주변 요소와 거리를 만들고, auto 가운데 정렬이나 제한적인 음수 값에 사용할 수 있다.

padding은 content와 border 사이의 간격이다.
배경색과 클릭 영역에 포함되며, 요소의 실제 크기에 영향을 준다.

두 속성이 헷갈릴 때는 테두리를 기준으로 보면 된다.
테두리 안쪽 공간이면 padding, 테두리 바깥 공간이면 margin이다.
반복 항목 사이의 균일한 간격이라면 margin과 함께 부모의 gap도 선택지에 넣는 것이 좋다.

참고 자료