여백 상쇄 (margin collapsing) 이해하기

1 minute read

프론트엔드 개발자라면 알고 있어야하는 여백 상쇄 (margin collapsing) 이해하기

여백 상쇄

여러 블록 요소가 나란히 있을 때 상단과 하단의 바깥 여백은 제일 큰 여백의 크기를 가진 단일 여백으로 결합 됩니다. 이를 여백 상쇄라고 합니다.

단, 플로팅 요소와 절대 위치를 지정한 요소의 여백은 상쇄되지 않습니다.

알아야 하는 이유

바깥쪽 여백 (margin)을 설정할 때 예기치 못한 결과가 발생할 수 있습니다.

  • 각 요소에 바깥쪽 여백을 설정했는데 인접한 두 요소가 바깥쪽 여백 하나를 공유합니다.
  • 부모요소 <section>이 갑자기 <h1> 과 같은 자식 요소의 바깥쪽 여백을 차지합니다.

이는 여백 상쇄 현상과 관련 있습니다. 기본적인 사례는 다음 세 가지 입니다.

기본 사례 3가지

1. 인접 형제

인접 형제 요소간의 바깥 여백은 더 큰 여백으로 상쇄됩니다.

첫 번째 요소는 바깥 여백이 10px입니다. margin 10px의 div 요소

두 번째 요소는 바깥 여백이 5px 입니다. margin 5px의 div 요소

Demo: https://jsfiddle.net/seungwoo321/L1u5bc0m/

2. 바깥쪽 여백이 설정된 자식 요소를 가진 부모 요소

첫째나 마지막의 자식 요소에 바깥쪽 여백이 설정된 경우입니다. 이 경우 부모 요소의 바깥쪽 여백은 자식 요소의 바깥쪽 여백과 함께 상쇄 됩니다. 마찬가지로 크기가 큰 바깥쪽 여백이 이기고 부모 요소에 적용됩니다.

예시 코드 입니다.

<div class="container">
  <div class="box" id="box1">
    box1
  </div>
  <div class="box" id="box2">
    box2
  </div>
</div>
.container {
  background-color: #1dfe2e;
  margin: 10px;
}
.box {
  background-color: #e794a9;
}
#box1 {
   margin: 5px; 
}
#box2 {
  margin: 50px;
}

예시 코드를 실행한 화면입니다.

이전 예제에서 살펴본 div 요소 두 개에 container 클래스를 가진 부모 요소를 추가했습니다.

div 요소 두 개에 container 클래스를 가진 부모 요소를 추가

첫 번째 자식 요소인 box1은 부모보다 바깥쪽 여백이 작아서 부모의 바깥쪽 여백으로 상쇄되었습니다.

첫 번째나 마지막 자식 요소의 여백 보다 부모의 여백이 큰 경우

두 번째 자식 요소는 부모보다 바깥쪽 여백이 크기 때문에 부모의 바깥쪽 여백이 상쇄되어서 아래쪽 바깥 여백은 자식요소의 여백으로 상쇄되었습니다.

첫 번째나 마지막 자식 요소의 여백이 부모보다 큰 경우

부모 요소와 인접한 div요소를 추가하면 확실하게 알 수 있습니다..

<div class="box" id="box3">
  box3
</div>
#box3 {
  padding: 10px;
}

box3 클래스를 가진 블록 요소를 부모 요소와 인접하게 추가

box3 클래스를 가진 블록 요소를 부모 요소와 인접하게 그려보면 box2의 바깥쪽 여백만 적용되고 부모 요소의 아랫쪽 바깥 여백 (margin-bottom) 은 상쇄된 것을 볼 수 있습니다.

부모 요소에 안쪽 여백, 인라인 콘텐츠 (자식 요소는 제외) 또는 테두리가 설정된 경우에는 이 동작이 발생하지 않고 자식 요소의 바깥쪽 여백이 콘텐츠를 감싸는 부모 요소에 추가됩니다.

부모 요소에 안쪽 여백 (padding)이 추가되면 바깥 여백은 상쇄되지 않습니다.

부모 요소에 안쪽 여백 (padding) 추가

부모 요소에 인라인 컨텐츠를 추가하면 바깥 여백은 상쇄되지 않습니다. 부모 요소에 인라인 컨텐츠 추가

부모 요소에 테두리가 설정된 경우 바깥 여백은 상쇄되지 않습니다. 부모 요소에 테두리가 설정된 경우 바깥 여백은 상쇄되지 않습니다.

demo: https://jsfiddle.net/seungwoo321/av3jrmkL/

3. 빈 블록

인라인 콘텐츠, 안쪽 여백, 테두리와 높이(height, min-height, max-height) 가 지정되지 않은 블록 요소의 경우 상단과 하단의 바깥 여백은 하나의 단일한 바깥 여백으로 병합됩니다.

<div class="container">

</div>
.container {
  margin: 10px;
}

빈 블록일 때

요소의 margin-top과 margin-bottom이 단일 바깥 여백으로 병합되었습니다.

Reference