FrontEnd/CSS

마진겹침 현상

_우지 2023. 6. 17. 21:15

마진겹침 현상이란?

동일한 BFC에 존재하는 블록 엘리먼트에 한해서 발생하는 현상이다. 오직 수직 방향에서만 적용된다. 2개의 마진이 겹칠 때 더 큰 마진으로 덮어 씌우는 방식이며 하나의 마진이 음수일 경우 더하는 방식을 취한다.

 

 

발생 예시

1. 인접한 엘리먼트

<div class="element1"></div>
<div class="element2"></div>
div {
  width: 100px;
  height: 100px;
  background-color: red;
}
.element1 { margin-bottom: 20px; }
.element2 { margin-top: 40px; }

 

위 적용예시를 보면 더 큰 마진인 40px 로 덮어씌워진 것을 확인할 수 있다. ( 첫번째 div의 margin-bottom이 적용되지 않은 모습이다.)

 

 

마진이 음수인 경우는 어떨까?

<div class="element1"></div>
<div class="element2"></div>
div {
  width: 100px;
  height: 100px;
  background-color: red;
}
.element1 { margin-bottom: -30px; }
.element2 { margin-top: 40px; }

40px + -30px 이 되어 10px 의 마진 겹침이 발생한다.

 

 

2. 부모와 처음 / 마지막 자식 사이에서 

<div class="parent">
  <div class="child">
  </div>
</div>
div {
  width: 100px;
  height: 100px;
}
.parent {
  background-color: red;
  margin-top: 20px; 
}
.child { 
  background-color: blue;
  margin-top: 20px; 
}

위와 같은 요소의 배치를 기대했지만 실제로 이루어지는 배치는 아래와 같다.

마진 겹침으로 인해 붉은색 div는 보이지 않게 되었다.

 

 

 

해결 방법

BFC 란?

용어정리를 위해 검색을 해봤는데, 딱 와닿는 설명이 없었다. 고민을 해본 끝에 정리하자면, 블록요소들이 쌓이는 레이아웃 틀 이라고 생각하기로 했다. 구분되는 BFC 가 존재할 때 마진 겹침이 발생하지 않는다.

 

 

BFC 가 생성되는 조건

  • html 루트 엘리먼트
  • float가 none 이 아닐 때 
  • postion이 absolute / fixed 일 때
  • overflow 가 visible 이 아닐 때
  • display가 flex / inline-flex 일 때

 

BFC가 생성되는 조건을 알았으니, 이제 위 예시에 대한 해결방법을 알아보도록 하자.

 

1. 인접한 레이아웃 예시의 경우에는 다음과 같이 하나의 BFC 를 가진다. 

따라서 마진 겹침이 발생한다. 이를 막기위해서는 위, 아래의 붉은색 div 를 새로운 BFC 를 가진 레이아웃의 자식으로 만들어줘야한다.

 

다음처럼 말이다. 두번째 div 요소를 새로운 BFC 내부로 분리하였다. 위에서 설명했듯이 float가 none 이 아니라면 새로운 BFC를 생성한다.

<div class="element1"></div>
<span class="wrapper">
  <div class="element2"></div>
</span>
div {
  width: 100px;
  height: 100px;
  background-color: red;
}
.element1 { margin-bottom: 20px; }
.element2 { margin-top: 40px; }

.wrapper {
   float: left;
}

 

더이상 마진 겹침이 발생하지 않는다.

 

 

 

2. 부모와 처음 / 마지막 자식 사이에서 예시를 보자.

<div class="parent">
  <span class="wrapper">
    <div class="child"></div>
  </span>
</div>
div {
  width: 100px;
  height: 100px;
}
.parent {
  background-color: red;
  margin-top: 20px; 
}
.child { 
  background-color: blue;
  margin-top: 20px; 
}

.wrapper {
  float: left;
}

기존 마진겹침이 발생한 예시

 

마진 겹침을 해결한 예시

 

 

파란색 영역을 새로운 BFC 를 가진 레이아웃을 자식으로 배치시킴으로써 마진 겹침을 해결할 수 있다.