Web/CSS

[CSS] 마진 상쇄(marign Collapsing)와 해결방법

Joonfluence 2022. 4. 20.

서론

형제 태그 간 marign 간격이 중복되어, 의도치 않은 방식으로 간격 조정이 될 때가 있습니다. 그럴 때 의심해볼만한 것은 마진병합. 오늘은 이에 대해서 알아보도록 하겠습니다.

본론

 

마진 상쇄란?

In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin. (W3C)

 

일반적으로 마진 병합(마진 병합 현상), 마진 겹침 등으로 더 많이 익숙하실 겁니다. (저도 그랬거든요..) 그러나 정확하게 알기 위해선, 항상 CSS 명세를 참조하는 것이 좋습니다. 명세에 따르면, collapsed margin이라고 합니다. 그래서 마진 상쇄라고 하죠.

 

마진상쇄가 발생하는 상황은?


1) 인접한 형제 사이 상하 마진이 겹칠 때

See the Pen collasping margin 01 by joonfluence (@joonfluence) on CodePen.

 


2) 부모와 자식 사이 상하 마진이 겹칠 때

 

  • 부모와 자손을 분리하는 콘텐츠가 없고(부모 블록에 테두리, 안쪽 여백, 인라인 부분이 없고)
  • 부모 블록에 테두리, 안쪽 여백, 인라인 콘텐츠가 없으며
  • 부모의 margin-bottom과 자손의 margin-bottom을 분리할 height, min-height, max-height가 존재하지 않는 경우 

위 3가지 조건을 모두 만족하면, 부모와 자손의 여백이 상쇄됩니다. 

See the Pen collasping margin 02 by joonfluence (@joonfluence) on CodePen.

 


3) 빈 요소의 상하 마진 겹칠 때

 

테두리, 안쪽 여백, 인라인 콘텐츠, height, min-height, max-height가 없으면 블록의 margin-topmargin-bottom이 서로 상쇄됩니다. 더 큰 값으로 상쇄됩니다.

See the Pen collasping margin 03 by joonfluence (@joonfluence) on CodePen.

 

 

마진상쇄 조건

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

 

마진상쇄 예외

  • 단, 플로팅 요소와 절대 위치(position: absolute)를 지정한 요소의 여백은 절대 상쇄되지 않습니다.
  • 또한 박스가 display: flex이거나 grid 일 때 내부 요소는 적용되지 않습니다.
  • 수평 마진은 상쇄되지 않습니다. 

 

마진병합현상 해결 방법

 

1) display: inline-block을 준다.

 

1번 케이스의 부모요소에 display: inline-block을 추가한 모습

 

이 방법은 모든 케이스에 다 적용할 수 있는 방법입니다. 마진 상쇄는 블록 요소에서만 발생되므로 inline-block을 주면 자연스레 사라집니다. 단, 이 경우 자식 요소에 존재하는 모든 마진 병합 현상이 사라지게 되므로 주의해야 합니다. 부모 요소에만 주고 싶다면, overflow: hidden을 줘야 합니다. 

 

2) display: flex, grid을 준다.

 

2번 케이스의 부모요소에 display: grid를 추가한 모습

부모 요소에 display: flex나 grid를 주면, 마진상쇄는 해결됩니다. 단, 경우에 따라서 박스 레이아웃이 변동될 수 있으므로 주의해야 합니다. 

 

3) 경계를 만든다. 

2번 케이스의 부모요소에 border를 추가한 모습

 

이건 2번 케이스에만 적용됩니다. 부모 요소와 자식 요소 사이에 border나 padding 혹은 인라인 컨텐츠가 존재하는 경우, 마진 상쇄가 발생하지 않습니다. 

 

4) margin 대신 padding으로 간격을 조정한다.

 

가장 간단합니다. 하지만 padding의 경우 박스 크기가 커지게 만들고 이는 디자인의 통일성을 깰 수 있기 때문에, 항상 올바른 해답은 아닐 수 있습니다. 

 

마무리

이상으로 읽어주셔서 감사합니다! 더 좋은 글로 찾아뵙겠습니다 :)

 

참고사이트

https://www.w3.org/TR/CSS2/box.html#collapsing-margins

https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing

https://stackoverflow.com/questions/18963421/wanted-css-grid-system-and-collapsing-margins

https://velog.io/@raram2/CSS-%EB%A7%88%EC%A7%84-%EC%83%81%EC%87%84Margin-collapsing-%EC%9B%90%EB%A6%AC-%EC%99%84%EB%B2%BD-%EC%9D%B4%ED%95%B4

https://velog.io/@ursr0706/%EB%A7%88%EC%A7%84margin

https://velog.io/@raram2/CSS-%EB%A7%88%EC%A7%84-%EC%83%81%EC%87%84Margin-collapsing-%EC%9B%90%EB%A6%AC-%EC%99%84%EB%B2%BD-%EC%9D%B4%ED%95%B4

반응형

댓글