개발 카테고리

Collapsing Margin 마진 겹침 현상

초이스 페이스 2020. 6. 16. 18:00

가끔보면 내가 설정한 마진보다 적게 들어가거나, 감싸는 부모 밖으로 마진이 튀어나갈 때가 있다. CSS 에서는 인접하는 element 의 마진이 서로 만나면 합쳐지는 등 예상하기 어려운 방식으로 동작한다.

 

margin 겹침 현상이 벌어지는 세 가지 케이스를 살펴보려고 한다.

 

 

 

첫 번째 케이스

 

아래와 같이 만들어보자.

<!DOCTYPE html>
<html>
    <head>
        <style>
          #id_grandparent {
          	width: 300px;
            border: 1px solid lightpink;
          }
          #id_parent {
            width: 300px;
            height: 100px;
            background-color: lightblue;
          }
          #id_child {
            width: 300px;
            height: 100px;
            background-color: lightseagreen;
            margin-top: 50px;
          }
        </style>
    </head>
    <body>
      <div id="id_grandparent">
        <div id="id_parent">
          <div id="id_child">
  
          </div>
        </div>
      </div>
    </body>
</html>

 

grandparent 에 padding 이 없고, parent 에도 margin 이 없는데, grandparent 안에 빈공간이 존재한다.

 

이게 바로, id_child 의 margin-top 이다.

 

상식적으로, id_child 는 id_parent 안에 있으므로, id_parent 의 크기는 id_child 의 크기에다가 margin 까지 포함해야될 것 같은데, id_child 의 마진이 parent 밖으로 튀어나와있는 것이다.

 

margin-bottom 은 어떨까? 마찬가지로 넘친다.

 

<!DOCTYPE html>
<html>
    <head>
        <style>
          #id_grandparent {
            width: 300px;
            border: 1px solid lightpink;
          }
          #id_parent {
            width: 300px;            
            background-color: lightblue;
          }
          #id_child {
            width: 300px;
            height: 100px;
            background-color: lightseagreen;
            margin-bottom: 50px;            
          }
        </style>
    </head>
    <body>
      <div id="id_grandparent">
        <div id="id_parent">
          <div id="id_child">
  
          </div>
        </div>
      </div>
    </body>
</html>

 

그런데 margin-left 와 margin-right 은 parent 안에 포함되고, margin-top, margin-bottom 처럼 튀어나오지 않는다.

 

 

 

<!DOCTYPE html>
<html>
    <head>
        <style>
          #id_grandparent {
            width: 300px;
            border: 1px solid lightpink;
          }
          #id_parent {
            width: 300px;
            background-color: lightblue;
          }
          #id_child {            
            height: 100px;
            background-color: lightseagreen;
            margin: 50px;            
          }
        </style>
    </head>
    <body>
      <div id="id_grandparent">
        <div id="id_parent">
          <div id="id_child">
  
          </div>
        </div>
      </div>
    </body>
</html>

 

 

 

 

 

그러면 vertical margin 에 대해서는 parent 밖으로 튀어나올 수 있다는 것을 확인했다.

 

그럼 이렇게 되지 않고, margin까지 다 parent 안에 있도록 하고 싶으면 어떻게 할까?

 

그 튀어나오는 부분에 padding 을 주거나, border 를 주면 된다.

 

 

id_parent 에 padding-top 을 1px 만 줘도 이렇게 id_child 의 margin-top 이 id_parent 안에 위치하게 된다.

        <style>
          #id_grandparent {
            width: 300px;
            border: 1px solid lightpink;
          }
          #id_parent {
            width: 300px;
            padding-top: 1px;
            background-color: lightblue;
          }
          #id_child {            
            height: 100px;
            background-color: lightseagreen;
            margin-top: 50px;            
          }
        </style>

혹은 border-top 을 주면 된다. 여기선 투명하게 transparent 로 잡았다.

        <style>
          #id_grandparent {
            width: 300px;
            border: 1px solid lightpink;
          }
          #id_parent {
            width: 300px;
            border-top: 1px solid transparent;
            background-color: lightblue;
          }
          #id_child {            
            height: 100px;
            background-color: lightseagreen;
            margin-top: 50px;            
          }
        </style>

 

 

 

두 번째 케이스

이번에는, 부모-자식 간에 생기는 것이 아니라 형제 간 생기는 문제를 살펴보자.

 

id_child1 과 id_child2 는 모두 id_parent 의 자식으로 들어가있고, id_child1 은 아래로 margin-bottom 이 있고, id_child2 는 위로 margin-top 이 있어서 두 마진이 겹친다. 둘다 margin 값을 50px 을 줬다.

 

<!DOCTYPE html>
<html>
    <head>
        <style>

          #id_parent {
            width: 300px;            
            border: 1px solid red;
          }
          #id_child1 {            
            height: 100px;
            background-color: lightgreen;
            margin-bottom: 50px;            
          }
          #id_child2 {            
            height: 100px;
            background-color: lightblue;
            margin-top: 50px;            
          }
        </style>
    </head>
    <body>

        <div id="id_parent">
          <div id="id_child1">
  
          </div>
          <div id="id_child2">
  
          </div>
        </div>

    </body>
</html>

실제로 실행해보면 두 마진이 겹쳐서 50px 어치의 여백 밖에 없다.

 

즉 아래와 같이 id_child1 의 margin-bottom 을 0px 로 두는 것과 50px 로 두는 것이 차이가 없어진다. 왜냐면 id_child1 의 margin-bottom 이 있더라도 id_child2 의 margin-top 과 겹쳐져버리기 때문이다.

	<style>
          #id_parent {
            width: 300px;            
            border: 1px solid red;
          }
          #id_child1 {            
            height: 100px;
            background-color: lightgreen;
            margin-bottom: 0px;            
          }
          #id_child2 {            
            height: 100px;
            background-color: lightblue;
            margin-top: 50px;            
          }
        </style>

 

그런데, id_child1 의 마진을 키우다보면 50px 을 넘어갈 때 여백이 커지게 된다.

 

겹쳐지는 두 마진 값 중 큰 값으로 최종 여백이 결정되기 떄문이다.

 

<!DOCTYPE html>
<html>
    <head>
        <style>
          #id_parent {
            width: 300px;            
            border: 1px solid red;
          }
          #id_child1 {            
            height: 100px;
            background-color: lightgreen;
            margin-bottom: 100px;            
          }
          #id_child2 {            
            height: 100px;
            background-color: lightblue;
            margin-top: 50px;            
          }
        </style>
    </head>
    <body>

        <div id="id_parent">
          <div id="id_child1">
            id_child1
          </div>
          <div id="id_child2">
            id_child2
          </div>
        </div>

    </body>
</html>

 

 

 

 

세 번째 케이스

 

이번엔, div 를 3개를 수직으로 쌓아놓고, 가운데 div(id_child2) 가 아무것도 없도록 비워보자(내용도 없고, margin, padding, border 없도록) 이 때, 위에 있는 div 인 id_child1 은 margin-bottom 을 갖고, id_child2 는 margin-top 을 갖는다. 이 두 마진이 id_child2 를 뚫고 겹친다.

 

<!DOCTYPE html>
<html>
    <head>
        <style>
          #id_parent {
            width: 300px;            
            border: 1px solid red;
          }
          #id_child1 {            
            background-color: lightgreen;       
            margin-bottom: 100px;            
          }
          #id_child2 {
          }
          #id_child3 {            
            background-color: lightgreen;
            margin-top: 100px;           
        
          }

        </style>
    </head>
    <body>
        <div id="id_parent">
          <div id="id_child1">id_child1</div>
          <div id="id_child2"></div>
          <div id="id_child3">id_child3</div>
        </div>
    </body>
</html>

 

 

복합 케이스

아래와 같이, 첫 번째 케이스 처럼 id_child1 의 margin-bottom 은 id_parent 를 아래로 뚫고 나오고, 케이스 2번 처럼,

id_child2 는 id_parent 방향으로 있다면, 둘이 겹칠까?

<!DOCTYPE html>
<html>
    <head>
        <style>
          #id_grandparent {
          	width: 300px;
            border: 1px solid lightpink;
          }
          #id_parent {
            width: 300px;
            background-color: lightblue;
          }
          #id_child1 {
            width: 300px;
            height: 100px;
            background-color: lightseagreen;
            margin-bottom: 50px;
          }
          #id_child2 {
            width: 300px;
            height: 100px;
            background-color: lightseagreen;
            margin-top: 50px;
          }
        </style>
    </head>
    <body>
      <div id="id_grandparent">
        <div id="id_parent">
          <div id="id_child1">
            id_child1
          </div>            
        </div>
        <div id="id_child2">
          id_child2
        </div>
      </div>
    </body>
</html>

이 경우에도 겹침을 알 수 있다.