margin 병합 현상 | 누가 내 마진을 먹었을까?

    ✨누가 나 몰래 margin을 먹은것같아요

     css로 작업을 하다보면 가장 많이 스타일 적용하는것에 쓰이는것이 padding, 그리고 margin일것이다. 여기서 이 margin은 독특한 property인데, 기본적으로는 스타일을 정의하는데 있어 이로운 녀석이지만 위 아래로 margin이 붙을 경우 조금은 곤란한 상황이 벌어질 수 있다. 위 아래의 요소에 margin값이 붙어있다면, 그중 가장 큰 margin값으로 통일되어서 그 요소간 간격이 결정되는 상황이 생긴다. 즉 목소리가 큰 요소가 작은 요소의 margin을 잡아먹는 이 현상을 바로 'margin collapse', margin 병합(혹은 결합)현상이라 불린다. 대개 margin병합이 일어날 수 있는 환경은 인접해있는 블록요소끼리 상하단이 맞물려 있을때 발생한다. 좌우로는 margin 병합현상이 발생하지 않는다.

     

     기본적으로 부모와 자식요소간의 관계에 있어서 부모에 margin값이 주어졌을때 외부와 부모요소간의 margin값은 일정하게 유지될 수 있으나 자식요소들에게까지 margin이 적용되면 자식요소간 margin 간격이 중복으로 적용되어 자식들만 간격이 중복으로 보여질 수 있다. margin collapse 는 이런 현상을 방지하기위해 margin 겹침을 허용했으나 이 방향이 옳지 못하게 적용되면 레이아웃을 만드는데 있어 큰 걸림돌이 있기에 해당 이슈는 해결하고 넘어가야 한다.

     

    ✨margin에게 어떤일이 일어났길래?

     코드와 간단한 그림을 통해 margin 병합에 대해서 한번 알아보자.

    <style>
        * {margin:0px; padding:0px;}
        section {width:300px; height:800px; margin:200px auto;}
        ul,li {list-style:none;}
        h1 {text-align:center;}
        ul {
            margin:20px auto; width:300px; background-color:violet;
        }
        ul li {
            width:250px; height:250px; background-color:gold; margin:25px;
        }
    </style>
    
    </head>
    <body>
        <section>
            <h1>마진병합을 알아봅시다</h1>
            <ul>
                <li></li>
                <li></li>
            </ul>
        </section>
    </body>

    왼쪽처럼 나와야 하는데... 실상은 오른쪽으로 나오는 상황

     코드만 보면 왼쪽 그림과 같이 노란색 박스 두개를 어떤 큰 보라색 박스 안에 넣어서 아래로 정렬시키고 싶다고 가정해보자. 그러면 왼쪽과도 같은 그림이 나와야 하건만 정작 평소대로 코딩을 하면 오른쪽과 같은 상황이 발생한다.

     아니 위의 요소는 어디에 가부려서 H모양이 되어버렸지....? 위의 요소는 어디로 날라가버린겨...? 이 상황을 설명하기위해 바로 'margin 병합'현상을 알아야 하며 이를 해결해야 한다.

     

     

    ✨마진 병합을 해제하는 대표적인 방법

    도데체 왜이러는 걸까요?

     해당 빈 공간의 margin 겹침현상을 해결하기 위해서는 크게 세가지의 방법이 시도될 수 있다.

    1. 인접한 공간에 무언가를 넣어보기
    2. padding 값을 넣기
    3. border 값을 넣어주기
    4. 부모요소에 overflow:hidden값을 넣어주기

    결과만 말해보자면 4번, 부모요소에 overflow:hidden 값을 넣어주기가 정답이 되겠다. 차례대로 1,2,3번의 경우 어떤 이슈가 발생하는지 알아보도록 해보자.


    1. 인접한 공간에 무언가를 넣어보기

    <style>
        * {margin:0px; padding:0px;}
        section {width:300px; height:800px; margin:200px auto;}
        ul,li {list-style:none;}
        h1 {text-align:center;}
        ul {
            margin:20px auto; width:300px; background-color:violet;
        }
        ul li {
            width:250px; height:250px; background-color:gold; margin:25px;
        }
    </style>
    
    </head>
    <body>
        <section>
            <h1>마진병합을 알아봅시다</h1>
            <ul>
                <p>이렇게</p>
                <li></li>
                <li></li>
                <p>텍스트를 넣으면?</p>
            </ul>
        </section>
    </body>​

    예쁘지 아니하다...

    p 태그를 li 위쪽에 추가하여 한번 넣어보았다. margin 병합이 풀리긴 하지만 의도한 디자인에서 상당히 많이 벗어난 디자인이 되어버린다. 가장 첫번째로 탈락...!!


    2. padding값을 넣어주기

    <style>
        * {margin:0px; padding:0px;}
        section {width:300px; height:800px; margin:200px auto;}
        ul,li {list-style:none;}
        h1 {text-align:center;}
        ul {
            margin:20px auto; width:300px; background-color:violet;
            padding:10px;
        }
        ul li {
            width:250px; height:250px; background-color:gold; margin:25px;
        }
    </style>
    
    </head>
    <body>
        <section>
            <h1>마진병합을 알아봅시다</h1>
            <ul>
                <li></li>
                <li></li>
            </ul>
        </section>
    </body>​

    예쁘지 아니하다....02

    부모요소에 padding값을 넣어보았다. 1픽셀만 넣어도 충분하지만 이 또한 의도한 디자인과도 1px정도는 멀어질 수 있는 방법이다. 이 방법 또한 안녕...


     

    3. border 값을 넣어주기

    <style>
        * {margin:0px; padding:0px;}
        section {width:300px; height:800px; margin:200px auto;}
        ul,li {list-style:none;}
        h1 {text-align:center;}
        ul {
            margin:20px auto; width:300px; background-color:violet;
            border:10px solid burlywood;
        }
        ul li {
            width:250px; height:250px; background-color:gold; margin:25px;
        }
    </style>
    
    </head>
    <body>
        <section>
            <h1>마진병합을 알아봅시다</h1>
            <ul>
                <li></li>
                <li></li>
            </ul>
        </section>
    </body>

    낫 프리티

    마찬가지로 부모요소에 border값을 넣어주었다. 그나마 불균형적으로 크기가 어색하진 않지만, 이 방법 또한 원래 의도한 박스 사이즈의 요소에서 벗어나는 작성방법이다. 그래서 우리는! 다음과 같은 방법을 써서 margin 겹침을 해제하여야 한다.


     

    4. 부모요소에 overflow:hidden값을 넣어주기

    <style>
        * {margin:0px; padding:0px;}
        section {width:300px; height:800px; margin:200px auto;}
        ul,li {list-style:none;}
        h1 {text-align:center;}
        ul {
            margin:20px auto; width:300px; background-color:violet; overflow:hidden;
        }
        ul li {
            width:250px; height:250px; background-color:gold; margin:25px;
        }
    </style>
    
    </head>
    <body>
        <section>
            <h1>마진병합을 알아봅시다</h1>
            <ul>
                <li></li>
                <li></li>
            </ul>
        </section>
    </body>

    완-벽

     드디어 찾았다, margin 결합문제를 해결할 수 있는 요것....부모요소의 속성값에 overflow:hidden 값을 넣어주면 부모요소에 가상의 block 요소가 넣어지게 되면서 부모의 margin과 자식의 margin이 별개로 똑! 떨어지게 된다. 그렇기에 자식요소인 li들의 위, 아래 여백이 표현되며 두 자식간의 margin 값은 그대로 병합이 된다.

     

     블록요소간 margin 병합 현상은 부모태그에 overflow:hidden 값을 넣어주는것으로 해결하도록 하자.


    ✨내가 깨달은 점

    • 어렴풋하게 레이아웃을 여러개 만들어가면서 margin 겹침현상을 일종의 '공식'으로만 알고 있었다. 이번기회에 개념으로서 다시한번 기본을 다잡을 수 있었다.
    • 간단하게 작성해보겠다고 다짐했는데 자꾸 뭔가 말이 많아지는것 같다. 조금은 더 간결하게 써보는 방법을 생각해봐야 겠다.

    ✨다음에 해보면 좋을 시도

    • overflow의 요소에 hidden 속성이 말고도 다른 용례가 존재하는데 이 속성에 대해서 좀 더 알아볼 것!

    댓글