마진 상쇄(margin collapse)

이일우·2023년 2월 15일

공부하기

목록 보기
4/42

여러 블록의 위쪽 및 아래쪽 바깥 여백(마진)은 경우에 따라 제일 큰 여백의 크기를 가진 단일 여백으로 결합(상쇄)되곤 합니다. 이런 동작을 여백 상쇄라고 부릅니다. 단, 플로팅 요소와 절대 위치를 지정한 요소의 여백은 절대 상쇄되지 않습니다. -MDN-

마진 상쇄, 마진 겹침이라 불리우는 이 현상은 인접한 2개의 마진이 하나로 합쳐지는 현상이다.
개발자중에 이러한 현상을 원하는 사람은 아무도 없을것이다. 하지만 나는 의도치 않게 이러한 현상이 일어났고, 어떤 상황에서 마진 상쇄가 일어나고, 해결 방법이 무엇인지 알아보겠다.

마진 상쇄의 3가지

인접 형제간 마진이 겹칠 때

인접 형제간 마진이 겹칠 경우, 두 마진값을 비교해 더 큰 마진값으로 상쇄합니다. 겹친 마진값이 동일할 경우 중복을 상쇄합니다.

부모와 자손을 분리하는 콘텐츠가 없을 때

부모 박스와 첫번째 자식 박스의 상단 마진이 겹칠 때, 혹은 부모 박스와 마지막 자식 박스의 하단 마진이 겹칠 때 자식 마진이 상쇄되어 부모의 바깥 마진만 나타납니다.

빈 블록의 상하 마진이 겹칠 때

빈 블록(height가 0인 블록)인 경우(height, min-height, max-height가 없는 경우) 자신의 상단 마진과 하단 마진중 큰 값으로 상쇄합니다.

참고사항

  • 세 개 이상의 여백 상쇄는 위의 기본 상황이 서로 결합되어 발생합니다.
  • 위의 규칙은 바깥 여백이 0이어도 적용되므로, 두 번째 규칙을 만족하는 경우 부모의 바깥 여백이 0이건 아니건 자손의 바깥 여백은 부모 밖으로 나오게 됩니다.
  • 음수 값을 가진 바깥 여백을 포함할 경우, 상쇄된 여백의 크기는 제일 큰 양수 여백과 제일 작은(음의 방향으로, 절댓값이 제일 큰) 여백의 합이 됩니다.
  • 모든 바깥 여백이 음수 값을 가질 경우, 상쇄된 여백의 크기는 제일 작은(음의 방향으로, 절댓값이 제일 큰) 여백의 크기가 됩니다. 인접 요소와 중첩 요소 모두에 적용됩니다.
  • 마진 상쇄는 인접한 두 박스가 온전한 block 요소일 경우에만 적용됩니다.

마진 상쇄 예외

  • 박스가 position: absolute 된 상태
  • 박스가 float: left/right 된 상태 (단, clear 되지 않은 상태)
  • 박스가 display: flex 일 때 내부 flexbox item
  • 박스가 display: grid 일 때 내부 grid item
  • 좌우 마진은 상쇄되지 않습니다.

해결 방법

  1. display를 block에서 다른걸로 바꾸기
    마진 상쇄는 display:block에서만 일어나기 때문에 inline-block, flex, grid로 바꿔주시면 해결됩니다.
    inline-block의 경우 자식 요소에 존재하는 모든 마진 병합 현상이 사라지게 되므로 주의해야 합니다. 부모 요소에만 주고 싶다면, overflow: hidden을 줘야 합니다.
    flex와 grid로 변경 시 경우에 따라서 박스 레이아웃이 변동될 수 있으므로 주의해야 합니다.

  2. 부모와 자손을 분리하는 콘텐츠가 없을 때 부모 요소와 자식 요소 사이에 border나 padding 혹은 인라인 컨텐츠가 존재하는 경우, 마진 상쇄가 발생하지 않습니다.

  3. margin 대신 padding으로 간격을 조정하면 마진 상쇄가 발생하지 않습니다. 단, 박스 크기가 커지고 디자인의 통일성을 방해할 수 있습니다.

참고 자료 출처

https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing
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://joonfluence.tistory.com/653

0개의 댓글