2016. 12. 21. 15:00

css에는 마진 상쇄(margin collapsing) 혹은 마진 겹침(margin overlap)라는 현상이 있습니다.

 

탑과 바텀에 마진이 있는 경우 큰 쪽 한 개만 적용되는 현상을 말합니다.

 

아래위 마진이 겹쳐 있습니다.

 

1. 현상 확인

아래 코드를 실행해봅시다.

 

 

 

탑 마진(margin-top)을 20px주고

바텀마진을(margin-bottom) 20px를 줬습니다.

그런데 결과물은 20px 입니다,

 

 

이것을 마진 상쇄(margin collapsing), 마진 겹침(margin overlap) 현상이라고 합니다.

 

2. 현상의 이해

마진 상쇄가 일어나는 이유는 레이아웃의 예외제어를 쉽게 하기 위해서입니다.

보통 줄 단위(row)의 레이아웃의 경우 마진상쇄가 일어나지 않으면 맨 위에 줄과 맨 아래 줄을 따로 처리해야 하는 문제가 발생합니다.

아래 예제를 통해 문제를 확인해 봅시다.

 

 

 

같은 css를 적용했지만 맨 위칸과 맨 아래칸 마진이 달라서 레이아웃이 이상해 보입니다.

 

 

 

이 문제를 해결하기 위해선 맨 위 칸과 맨 아랫간에 별도의 css를 적용해야 하는 문제가 발생합니다.

그래서 마진 상쇄 현상이 필요한 것이죠.

 

 

마진 상쇄 현상은 아래와 같은 3가지 상황에서 일어납니다.

 

인접 형제 요소(Adjacent siblings)
부모 및 맏이/막내 요소(Parent and first/last child)
빈 블록(Empty blocks)

(참고 : w3c - 8.3.1 Collapsing margins, MDN - 마진 상쇄 정복)

 

2-1. 인접 형제 요소( Adjacent siblings )

붙어 있는 형제 요소끼리 마진 상쇄가 일어나는 현상을 말합니다.

아래위로만 발생합니다.

좌우는 발생하지 않는다는 것이죠.

 

아래 코드를 확인해 봅시다.

 

 

 

아래위로는 마진 상쇄가 일어나지만 좌우로는 일어나지 않는 것을 볼 수 있습니다.

 

 

 

 

2-2. 부모 및 맏이/막내 요소(Parent and first/last child)

부모의 특정요소가 없다면 자식요소의 'margin-top'과 'margin-bottom'이 상쇄되는 현상을 말합니다.

 

특정요소는

 

첫 줄이면

border
padding
inline(화면에 표시되는 글자 같은 것들)

 

이고 마지막 줄이면

border
padding
inline

height

min-height
max-height

 

 

첫 번째 줄일 때 'margin-top'이 상쇄되고

마지막 줄일 때 'margin-bottom'이 상쇄됩니다.

 

아래 코드를 봅시다.

 

 

 

 

 

div가 여러 번 중첩되었지만 'margin-top'과 'margin-bottom'는 한 번만 적용된 것을 확인할 수 있습니다.

 

 

 

 

2-3. 빈 블록(Empty blocks)
근접한 블록이 특정요소가 없으면 마진이 상쇄됩니다.

 

특정요소는

border
padding
inline

height

min-height
max-height

 

아래코드는 주황색(orange)과 파란색('blue')의 내용을 뺀 코드입니다.

 

 

 

주황색은 가로마진이 남아있어 그대로 있지만 파란색은 마진이 상쇄되어 존재가 지워졌습니다

 

 

 

3. 마진 상쇄 피하기

 

그렇다면 마진 상쇄가 필요 없는 경우 어떻게 해야 할까요?

간단하게 위에서 말했던 특정요소를 css에 포함 시키면 됩니다.

 

공통으로 사용되는

border
padding
inline

를 이용하면 됩니다.

 

 

 

 

하단 마진만 처리할 거면 선택의 폭은 더 넓어지죠.

 

마무리

이런 디스플레이에 영양을 주는 현상을 정의 하면서 우회 방법이 없다는 게 좀 이상하네요.
이 현상을 피하려면 보더나 패딩같이 레이아웃에 영향을 주는 요소를 활용해야 합니다.

뭔가 레이아웃에 영향을 안 주는 방법을 찾고 싶은데 모르겠네요;;;