Margin on child element moves parent element

前端 未结 14 2168
广开言路
广开言路 2020-11-21 23:38

I have a div (parent) that contains another div (child). Parent is the first element in body with no

相关标签:
14条回答
  • 2020-11-22 00:35

    Neat CSS-only solution

    Use the following code to prepend a contentless first-child to the unintentionally moving div:

    .parent:before
    {content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}
    

    The advantage of this method is that you do not need to change the CSS of any existing element, and therefore has minimal impact on design. Next to this, the element that is added is a pseudo-element, which is not in the DOM-tree.

    Support for pseudo-elements is wide-spread: Firefox 3+, Safari 3+, Chrome 3+, Opera 10+, and IE 8+. This will work in any modern browser (be careful with the newer ::before, which is not supported in IE8).

    Context

    If the first child of an element has a margin-top, the parent will adjust its position as a way of collapsing redundant margins. Why? It's just like that.

    Given the following problem:

    <style type="text/css">
    div {position: relative;}
    .parent {background-color: #ccc;}
    .child {margin-top: 40px;}
    </style>
    
    <div class="parent"><!--This div moves 40px too-->
        <div class="child">Hello world!</div>
    </div>
    

    You can fix it by adding a child with content, such as a simple space. But we all hate to add spaces for what is a design-only issue. Therefore, use the white-space property to fake content.

    <style type="text/css">
    div {position: relative;}
    .parent {background-color: #ccc;}
    .child {margin-top: 40px;}
    .fix {position: relative;white-space: pre;height: 0px;width: 0px;overflow: hidden;}
    </style>
    
    <div class="parent"><!--This div won't move anymore-->
        <div class="fix"></div>
        <div class="child">Hello world!</div>
    </div>
    

    Where position: relative; ensures correct positioning of the fix. And white-space: pre; makes you not having to add any content - like a white space - to the fix. And height: 0px;width: 0px;overflow: hidden; makes sure you'll never see the fix.

    You might need to add line-height: 0px; or max-height: 0px; to ensure the height is actually zero in ancient IE browsers (I'm unsure). And optionally you could add <!--dummy--> to it in old IE browsers, if it does not work.

    In short, you can do all this with only CSS (which removes the need to add an actual child to the HTML DOM-tree):

    <style type="text/css">
    div {position: relative;}
    .parent {background-color: #ccc;}
    .child {margin-top: 40px;}
    
    .parent:before {content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}
    </style>
    
    <div class="parent"><!--This div won't move anymore-->
        <div class="child">Hello world!</div>
    </div>
    
    0 讨论(0)
  • 2020-11-22 00:35

    interestingly my favorite solution to this problem isn't yet mentioned here: using floats.

    html:

    <div class="parent">
        <div class="child"></div>
    </div>
    

    css:

    .parent{width:100px; height:100px;}
    .child{float:left; margin-top:20px; width:50px; height:50px;}
    

    see it here: http://codepen.io/anon/pen/Iphol

    note that in case you need dynamic height on the parent, it also has to float, so simply replace height:100px; by float:left;

    0 讨论(0)
提交回复
热议问题