중첩된 빈 블록 요소의 상단 마진(margin-top) 겹침 현상 이해하기

웹 페이지 레이아웃을 작성하다 보면 드물게 이런 현상을 겪게 되는데, 이런 현상이 원래 생긴다는 것을 모르고 맞닫뜨리면 굉장히 당황을 하게 됩니다.

전문적으로 레이아웃을 작성하는 개발자들도 자주 보는 현상이 아니기 때문에 원래 이런 현상이 발생한다는 것을 꼭 알고 있어야 합니다.

제목을 조금 더 길게 설명을 하자면

부모-자식 관계인 블록 요소 들의 상단에 마진(Margin)을 부여한 경우, 블록 태그 안에 내용(텍스트, 이미지 등 높이 값을 가지는 요소)이 없으면 상단 요소들의 마진이 가장 큰 높이 값 1개로 겹쳐집니다.

버그는 아닙니다. 

중접된 요소는 "display: block;" 속성을 가지고 있어야 하고, 요소 안에 블록 요소 말고는 다른 요소가 없는 경우에만 겹쳐지기 때문에 제한적인 특별한 상황에서만 발생하는 CSS의 특성입니다.

예를 들어 다음과 같이 중첩된 요소가 있으면

<div class="parent">
    <div class="child">
        <div class="grandchild">
            <span>텍스트 내용</span>
        </div>
    </div>
</div>

중첩된 3 블록 요소 모두에 상단 마진으로 "20px"를 부여합니다.

블록 요소의 크기나 좌우 마진은 영향을 미치지 않기 때문에 제외 합니다.

div{
    width: 200px;
}
span{
    color: white;
}
.parent{
    height: 200px;
    margin: 20px 0;
    background-color: #a22;
}
.child{
    background-color: #2a2;
    margin: 20px 0;
}
.grandchild{
    background-color: #22a;
    margin: 20px 0;
}

결과는 다음과 같이 웹 브라우저에 표시됩니다. 중첩된 3개의 "<div>" 요소에 적용된 3개의 마진이 20px 1개로 겹쳐집니다.

다음과 같이 "child" 클래스 블록에 텍스트 내용을 추가하면

<div class="parent">
    <div class="child">
        <span>상단 텍스트 내용</span>
        <div class="grandchild">
            <span>텍스트 내용</span>
        </div>
    </div>
</div>

다음과 같이 "grandchild" 클래스를 가진 최하단 블록 요소의 상단 마진은 상단 요소의 마진과 겹치지 않고 제대로 적용됩니다.

CSS의 블록 요소가 비어있는 경우 상단 마진이 상위에 있는 빈 블록 요소의 마진과 겹치는 현상은 버그가 아니므로 억지로 패딩이나 높이 값을 부여할 필요가 없으며, 내용 컨텐츠가 채워지면 상단 마진이 정상 적용됩니다.