CSS로 작업을 하다보면 마진이 겹치는 현상을 발견할 수 있습니다. 오늘은 이 Collapsing-margin
현상에 대해 알아보도록 하겠습니다.
Collapsing-Margin
마진 상쇄 현상을 MDN에서는 다음과 같이 정의하고 있습니다.
블록의top
및bottom
마진은 크기가 마진 중 가장 큰(또는 동일한 경우 하나만) 단일 마진으로 결합(상쇄)되며, 이를 마진 겹침 상쇄라고 합니다. 하지만floating
및position 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인 상태란?
height
/padding
/border
등 상하단으로 늘어나는 프로퍼티 값을 명시해주지 않았을 때- 내부에
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
등이 있으면 상쇄 현상이 적용되지 않았었는데, 이 경우에는 height
와 min-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
현상에 대해 알아보았습니다.
읽어주셔서 감사합니다🤟
'FRONT-END > CSS' 카테고리의 다른 글
[CSS] Pseudo-elements (placeholder, selection, first-letter) (1) | 2022.10.06 |
---|---|
[CSS] 결합/연결자 - Combinators (0) | 2022.10.06 |
[CSS] 적용 우선 순위 (1) | 2022.09.05 |
(CSS) display: flex에 여러 요소가 있을때 좌우 정렬 하는 방법 (30) | 2022.07.07 |
이미지 드래그 & 오른쪽 마우스 막는 방법 (38) | 2022.07.05 |