궁금한 내용을 검색해보세요!
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
서근 개발노트
티스토리에 팔로잉
FRONT-END/CSS

[CSS] Collapsing-Margin (마진 겹침 현상)

서근
QUOTE THE DAY

-
Written by SeogunSEOGUN

반응형

CSS로 작업을 하다보면 마진이 겹치는 현상을 발견할 수 있습니다. 오늘은 이 Collapsing-margin 현상에 대해 알아보도록 하겠습니다.

Collapsing-Margin

마진 상쇄 현상을 MDN에서는 다음과 같이 정의하고 있습니다.

블록의 topbottom 마진은 크기가 마진 중 가장 큰(또는 동일한 경우 하나만) 단일 마진으로 결합(상쇄)되며, 이를 마진 겹침 상쇄라고 합니다. 하지만 floatingposition absolute 요소의 마진은 절대 축소되지 않습니다.
-MDN

즉, 마진 상쇄는 어떤 두 개 이상의 블록(block)의 top 그리고 bottom의 마진이 겹칠 때 어느 한쪽 값만 적용하는 브라우저 자체의 규칙입니다.

 

마진 상쇄 현상은 죄(left) 우(right)에서는 일어나지 않고 위(top) 아래(bottom)에서만 일어나게 됩니다.

마진 상쇄 현상이 일어나는 상황

대표적인 block 요소인 div를 예로 들어 설명하도록 하겠습니다.

1. 상-하 마진이 겹칠 때

블록 요소의 겹쳐진 두 마진을 비교했을 때, 더 큰 마진의 값으로 상쇄해 랜더링 하게 됩니다. 만약 겹쳐진 값이 동일하다면 그중 하나를 상쇄해 랜더링 하게 됩니다.

See the Pen collapsing margin by 서근 (@seogun95) on CodePen.

위 코드를 보면 .first.second 클래스 모두 margin: 20px 0; 을 적용시켜 주었습니다. 하지만 결과를 보면 각 요소의 최상단과 최하단을 제외한 중복된 마진 20px이 상쇄된 것을 알 수 있습니다.

2. 빈 요소의 상하 마진이 겹칠 경우

높이가 0 인 상태의 블록 요소일 때는 위아래를 가르는 경계선이 없으므로, 자신의 상단 마진의 값과 하단 마진의 값을 비교해 더 큰 값으로 상쇄합니다.

 

높이가 0인 상태란?

  1. height / padding / border 등 상하단으로 늘어나는 프로퍼티 값을 명시해주지 않았을 때
  2. 내부에 inline contents가 존재하지 않는 요소일 때

겹쳐진 두 값이 동일할 경우에도 이 중복을 상쇄하게 됩니다. 특히 빈 요소와 인접 박스들 사이에 마진 상쇄 현상이 일어나는 구조에서는 이 빈 요소의 위아래 요소들의 마진을 상쇄하게 됩니다.

 

아래 예시를 보면 더 쉽게 알 수 있습니다.

See the Pen collapsing margin 2 by 서근 (@seogun95) on CodePen.

분명히 첫 번째 요소와 두 번째 요소의 상하의 마진이 20px가 있는데도 불구하고, 빈 요소의 상단 마진 100px(margin-bottom:100px도 상쇄됐다.)만 적용되는 것을 볼 수 있죠.

 

이 의미는 다시 한번 말해 빈 요소와 인접 박스들 간의 마진 상쇄가 일어나는 구조에서 상쇄가 여러 번 발생했다는 의미입니다.

그럼 만약, empty 클래스에 padding-top이 1 픽셀이라도 있으면 어떻게 될까요?

See the Pen collapsing margin 3 by 서근 (@seogun95) on CodePen.

 

결과에서 알 수 있듯이 empty 클래스는 더 이상 빈 요소가 아니게 됐으므로 상 하에 마진이 그대로 적용되게 됐습니다. 물론 emtpy 클래스 요소의 인접한 박스들의 마진 또한 상쇄됐습니다.

3. 부모 박스와 자식 박스의 상 하단의 마진이 겹칠 경우

부모 박스의 첫 번째 자식 혹은 마지막 자식의 상하단 마진이 겹칠 경우에는 조금 다른 형식으로 마진 상쇄 현상이 적용됩니다. 

 

위의 현상들에서는 height / min-height / padding / border 등이 있으면 상쇄 현상이 적용되지 않았었는데, 이 경우에는 heightmin-height의 값이 있더라도 상쇄 현상이 일어나게 됩니다. 

 

즉, 부모 박스와 자식 박스의 상 하단의 마진이 겹 칠경 우에 박스 사이의 경계를 padding / border / inline 콘텐츠 유무로만 판단하고 값을 주지 않았다면 마진이 겹쳐지게 됩니다.

 

따라서 부모와 첫 번째 혹은 마지막 자식 사이에 inline 콘텐츠가 없거나, 박스 사이 경계에 padding / border 등의 값이 없다면 마진이 겹치게 되므로, 자식 요소의 마진이 더 크던 작던 상관없이 상쇄된 마진은 부모 박스 바깥으로만 렌더링 되게 됩니다.

3-1 부모의 마진이 자식의 마진보다 클 때

See the Pen Untitled by 서근 (@seogun95) on CodePen.

부모의 margin-top: 100px이고, 자식의 margin-top: 20px으로 값을 주었을 때, 부모의 마진이 더 크므로 자식의 마진은 상쇄된다.

3-2 부모의 마진이 자식의 마진보다 작을 때

See the Pen Untitled by 서근 (@seogun95) on CodePen.

부모의 margin-top: 100px이고, 자식의 margin-top: 200px으로 값을 주었을 때, 자식의 마진이 더 크므로 부모의 마진은 상쇄된다.

이 같은 상쇄 현상은 부모의 마진과 자식의 마진이 같을 때도 중복된 마진은 상쇄되고, 상단뿐만 아니라 하단의 마진이 서로 겹친다면 동일한 상쇄 현상을 적용받게 됩니다.

상쇄 현상 해결 방법

이러한 마진 상쇄 현상을 해결하려면 위에서 언급했던 것처럼 부모 박스 상/하단에 padding 또는 border 값을 주어 경계선(벽)을 만들어주는 것이 좋습니다.

See the Pen collapsing margin 6 by 서근 (@seogun95) on CodePen.

마진 상쇄 현상 규칙 

  • 마진 상쇄는 인접한 두 박스가 온전한 block-level 요소일 경우에만 적용됩니다.
    (inline, inline-block, table-cell, table-caption 등의 요소는 block-level이 아닙니다.)
  • 마진 값이 0이더라도 상쇄 규칙은 적용됩니다.
  • 좌우 마진은 겹치더라도 상쇄되지 않습니다. (상/하 마진만 상쇄 효과가 적용됩니다.)

마진 상쇄 규칙 예외

아래 상황에서는 인접 요소 간의 상쇄 현상이 이뤄지지 않습니다.

  • 박스가 position: absolute 된 상태
  • 박스가 float: left/right 된 상태 (단, clear 되지 않은 상태)
  • 박스가 display: flex 일 때 내부 flexbox item
  • 박스가 display: grid 일 때 내부 grid item

오늘은 이렇게 Collapsing-margin 현상에 대해 알아보았습니다.

 

읽어주셔서 감사합니다🤟

 

참고 문헌 REFERENCE
 

CSS 마진 상쇄(Margin-collapsing) 원리 완벽 이해

마진 상쇄는 흔히 '마진 겹침 현상'이라고도 불립니다. (혹자는 '마진 빡침 현상'이라고도 합니다) 하지만 인과관계로 볼 때, 마진이 겹치게 되면 상쇄가 일어나기 때문에 영미권에서는 '마진 상

velog.io

 


잘못된 내용이 있으면 언제든 피드백 부탁드립니다.


서근


위처럼 이미지 와 함께 댓글을 작성할 수 있습니다.