본문으로 바로가기

마진 병합(여백 붕괴 현상)

category StyleSheet/CSS 2016. 8. 24. 07:00

collasing margins

CSS 에서는 마진 붕괴 또는 마진 병합이라고 불리는 현상이 있습니다.

이 바깥 여백의 충돌 현상은 5 더하기 5가 10이 되지 않는 현상으로 두 개의 바깥 여백이 하나가 되어 버린다는 의미로 collasing margins 라고 부릅니다.




바깥 여백의 붕괴

보통 어떤 요소의 아래쪽 바깥 여백이 다른 요소의 위쪽 여백과 만나는 경우 마진 병합(합쳐지는) 현상이 일어납니다.

이 두 여백은 각각의 여백이 더해진 공백이 생기는 것이 아니라 그 중 가장 큰 값만큼의 공백이 생기는 것을 마진 병합이라고 합니다.


다음의 마진 붕괴(병합)현상에 대한 예제 코드를 보면서 살펴보도록 합니다.

See the Pen 마진 병합 #1 by jaeheekim (@jaehee) on CodePen.


위의 코드는 h1 요소에 바깥 하단 여백을 20px 만큼 그리고 p 요소에서 바깥 상단 여백 15px 을 정의했습니다.

상식적으로는 두 여백을 더한 35px 만큼의 여백 공간이 생겨야 맞지만 그렇지 않습니다.

웹 브라우저는 그 중에서 가장 큰 값만큼만 여백을 생성하여 넣게 됩니다.

그래서 이 예제에서는 20px 만큼의 바깥 여백만 생성하게 됩니다.

아마도 이러한 상하 마진 병합을 많이 알려진 현상이기 때문에 낯설지 않을 지 모르지만 이러한 바깥 여백 붕괴현상은 상하 마진 여백에서만 발생하는 것이 아닙니다.


어떤 요소가 다른 요소 안에 포함되는 경우에도 마진 병합 현상이 발생하는데 이러한 케이스에 직면하지 못했던 사용자는 뜻하지 않게 뒤통수를 긁적긁적일 만한 상황이 만들어질 지도 모릅니다.

또 다른 마진 붕괴 현상은 부모 요소(컨테이닝 요소)에 자식 요소가 상하단 한쪽 방향으로 마진이 정의되어 있을 경우 발생하기도 합니다.


다음의 코드를 통해 부모, 자식간의 마진 붕괴 현상에 대해 살펴보도록 하겠습니다.(위의 예제에 이어서 작성함)

See the Pen 마진 병합 #2 by jaeheekim (@jaehee) on CodePen.

위 코드에서 .type02-02 요소에 표제어와 하단 단락 간의 바깥 여백을 20px 만큼 정의했습니다.

그리고 h2 요소이면서 자식 요소인 type02-inner 클래스에 바깥 위쪽 여백 10px 을 정의하였습니다.

이는 디자인에 따라 다르겠지만 여기서는 .type02-02(div요소) 와 또 다른 표제어(type02-inner) 사이에 간격을 준다고 가정하여 여백을 정의한 것입니다.

이러한 경우 일반적으로 div 위쪽 경계와 "또 다른 표제어" 텍스트 사이에 10px 만큼의 공간이 생긴다고 생각할 것입니다.

하지만 그렇지 않습니다.

실제로 이 여백은 divh2 사이에 생기는 것이 아니라 div 위쪽에 바깥 여백이 생기게 됩니다.

즉, 무조건 div 위쪽에 바깥 여백이 적용되게 됩니다.

이러한 현상도 상하 마진 병합과 마찬가지로 마진 여백 붕괴 현상이라고 합니다.


이러한 문제를 해결하는 방법으로는 두가지가 있습니다.

컨테이닝 박스(부모요소) 내에 작은 안쪽 여백(padding)을 정의하거나 경계선(테두리)을 입히는 것입니다.

경계선(테두리)이나 안쪽 여백이 두 바깥 여백 사이에 들어가게 되기 때문에 div 와 h2 의 두 바깥 여백은 더이상 만나지 않게 되는 것입니다.

위 코드에서 테두리와 안쪽 여백에 주석처리가 되어 있는데 둘 중 하나를 주석 처리를 제거하여 확인해 보면 여유 공간인 바깥 여백이 생기게 될 것입니다.


수직 방향의 바깥 여백이 서로 만나게 되면 한 요소가 다른 요소 안에 있는 경우라 해도 <div> 안에 <h2> 처럼 바깥 여백 붕괴가 발생한다.


이런 수직 방향의 마진 붕괴 현상때문에 흔히들 하는 실수중에 하나가 리스트형에 바깥 여백을 정의하는 경우가 있습니다.

위와 같은 현상을 잘 이해하고 있다면 어려움없이 해결할 수 있습니다.

예를 들어 li 요소에 공통 간격을 정의하기 위해 margin-top 을 정의한다고 가정해 봅니다.

그리고 디자인상 리스트 콘텐츠와 위쪽 콘텐츠 사이에 공간이 있다고 한다면 이 경우 li 에 상단 마진을 주고 ul 요소나 ul 을 감싼 부모요소(컨테이닝박스)중 하나에 margin-top 을 준다고 가정해 봅니다.

이렇게 스타일을 정의한 경우 스타일상 테두리(경계)와 같이 구분할 것이 없기 때문에 이 경우에도 역시 마진 붕괴현상이 일어날 것입니다.


위의 예제 코드를 가지고 계속해서 지금까지 설명한 경우를 살펴보도록 합니다.

See the Pen 마진 병합 #3 by jaeheekim (@jaehee) on CodePen.


위와 같이 리스트 위쪽에 단락이 있으면서 디자인상 단락과 리스트 콘텐츠 사이에 20px 의 여백이 존재한다고 가정했을 경우에 .outer 또는 ul 요소에 margin-top 을 정의하여 바깥 여백을 정의하려고 할 것입니다.

이러한 경우에 수직 방향 마진 붕괴 현상이 발생하기 때문에 배경이미지와 같은 테두리 색상을 정의하거나 티가 나지 않을 안쪽 여백(padding)을 정의하면 바깥 여백이 올바르게 적용될 것입니다.

물론 디자인에 따라 다르겠지만 반드시 바깥 여백을 주어야만 하는 상황이 아니라면 안쪽 여백으로만도 해결이 가능하겠지만 수직 마진 병합 현상을 다루기 위해 위와 같이 구성한 것입니다.



수평 방향의 바깥 여백(왼쪽과 오른쪽 바깥 여백)이나 float(부유한) 요소 간의 바깥 여백에는 여백 붕괴현상이 발생하지 않습니다.


float 요소 간의 바깥 여백에 마진 붕괴 현상이 생기는 않는 예제입니다.

See the Pen 마진 병합 #4(플롯요소는 마진붕괴현상 없음) by jaeheekim (@jaehee) on CodePen.


위 코드에는 플롯 요소가 두개 있으며 각 플롯 요소에 상단 마진이 적용되어 있으며 단락과의 공간을 더 주기 위해(설명하기 위함) 플롯된 부모요소에 상단 마진을 또 적용하였습니다.

이러한 경우에는 수직 방향의 마진 붕괴현상이 발생하지 않습니다. 






Jaehee's WebClub


'StyleSheet > CSS' 카테고리의 다른 글

Mobile Web(모바일 웹) #1  (0) 2016.09.06
CSS3 3D effect(perspective) #1  (0) 2016.08.26
CSS3 box-shadow  (0) 2016.08.23
CSS3 text-shadow  (0) 2016.08.22
줄 간격(line-height) 상속  (0) 2016.08.10