首页 文章

子元素上的边距移动父元素

提问于
浏览
335

我有 divparent ),其中包含另一个 divchild ) . Parent是 body 中的第一个元素,没有特定的CSS样式 . 我订的时候

.child
{
    margin-top: 10px;
}

最终的结果是我的孩子的顶部仍然与父母对齐 . 我的父母向下移动10px,而不是将孩子向下移动10px .

我的 DOCTYPE 设置为 XHTML Transitional .

What am I missing here?

编辑1
我的父母需要有严格定义的尺寸,因为它的背景必须从上到下显示在它下面(像素完美) . 因此,在其上设置垂直边距是 no go .

编辑2
这种行为在FF,IE和CR上是相同的 .

14 回答

  • 404

    Child elements with margins within DIVs找到了替代方案您还可以添加:

    .parent { overflow: auto; }
    

    要么:

    .parent { overflow: hidden; }
    

    这可以防止边距collapse . 边框和填充也是如此 . 因此,您还可以使用以下内容来防止上边距崩溃:

    .parent {
        padding-top: 1px;
        margin-top: -1px;
    }
    

    Update by popular request: 折叠边距的重点是处理文本内容 . 例如:

    <style type="text/css">
        h1, h2, p, ul {
            margin-top: 1em;
            margin-bottom: 1em;
        }
    </style>
    
    <h1>Title!</h1>
    <div class="text">
        <h2>Title!</h2>
        <p>Paragraph</p>
    </div>
    <div class="text">
        <h2>Title!</h2>
        <p>Paragraph</p>
        <ul>
            <li>list item</li>
        </ul>
    </div>
    

    因为浏览器会折叠边距,所以文本会按照您的预期显示,并且 <div> 包装标记不会加倍 . <h2><p> 的边距不会相加,而是相互滑动(它们会折叠) . <p><ul> 元素也是如此 .

    可悲的是,有了现代设计,当你明确想要一个容器时,这个想法可能会让你感到困惑 . 这在CSS中称为新的block formatting context . overflow 或边缘技巧会给你这个 .

  • 1

    这是正常行为(至少在浏览器实现中) . 保证金不会影响孩子相对于父母的位置,除非父母有填充,在这种情况下,大多数浏览器会将孩子的边距添加到父母的填充中 .

    要获得所需的行为,您需要:

    .child {
        margin-top: 0;
    }
    
    .parent {
        padding-top: 10px;
    }
    
  • 11

    尽管所有的答案都解决了这个问题,但它们还是需要权衡利弊/调整/妥协

    • floats ,你必须浮动元素

    • border-top ,这会向父母推送至少1px,然后应该通过向父元素本身引入 -1px margin来调整 . 当父亲已经具有相对单位的 margin-top 时,这可能会产生问题 .

    • padding-top ,与使用 border-top 效果相同

    • overflow: hidden ,当父级应显示溢出内容时,不能使用,如下拉菜单

    • overflow: auto ,为具有(有意)溢出内容(如阴影或工具提示的三角形)的父元素引入滚动条

    可以使用CSS3伪元素解决此问题,如下所示

    .parent::before {
      clear: both;
      content: "";
      display: table;
      margin-top: -1px;
      height: 0;
    }
    

    https://jsfiddle.net/hLgbyax5/1/

  • 6

    将样式 display:inline-block 添加到子元素

  • 1

    父元素不能为空,至少在子元素之前放置 &nbsp; .

  • 44

    这对我有用

    .parent {
    padding-top: 1px;
    margin-top: -1px;
    }
    
    .child {
    margin-top:260px;
    }
    

    http://jsfiddle.net/97fzwuxh/

  • 1

    我发现,在你的.css>中,如果你将div元素的display属性设置为 inline-block ,它就可以解决问题 . 保证金将按预期运作 .

  • 17

    .child 中包含的 margin 元素正在折叠 .

    <html>
    <style type="text/css" media="screen">
        #parent {background:#dadada;}
        #child {background:red; margin-top:17px;}
    </style>
    <body>
    <div id="parent">
    
        <p>&amp;</p>
    
        <div id="child">
            <p>&amp;</p>    
        </div>
    
    </div>
    </body>
    </html>
    

    在此示例中, p 正在从浏览器默认样式接收 margin . 浏览器默认 font-size 通常为16px . 通过 #child 上的 margin-top 超过16px,你会开始注意到它的位置移动 .

  • 1

    我也遇到过这个问题但更喜欢防止负边距黑客,所以我放了一个

    <div class="supercontainer"></div>

    在它周围所有有填充而不是边距 . 当然这意味着更多的divitis,但它可能是最干净的方法来做到这一点 .

  • 6

    有趣的是,我最喜欢的解决这个问题的方法还没有在这里提到:使用浮动 .

    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;}
    

    在这里看到:http://codepen.io/anon/pen/Iphol

    请注意,如果您需要父级的动态高度,它也必须浮动,所以只需将 height:100px; 替换为 float:left;

  • 1

    在我知道正确答案之前我发现的另一种解决方案是向父元素添加 transparent border .

    你的盒子会使用额外的像素......

    .parent {
        border:1px solid transparent;
    }
    
  • 2

    纯粹的CSS解决方案

    使用以下代码将无内容的第一个子项添加到无意中移动的div:

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

    此方法的优点是您不需要更改任何现有元素的CSS,因此对设计的影响最小 . 接下来,添加的元素是一个伪元素,它不在DOM树中 .

    对伪元素的支持很广泛:Firefox 3,Safari 3,Chrome 3,Opera 10和IE 8 . 这适用于任何现代浏览器(小心使用较新的 ::before ,IE8不支持) .

    上下文

    如果元素的第一个子元素具有 margin-top ,则父元素将调整其位置以折叠冗余边距 . 为什么?就是这样 .

    鉴于以下问题:

    <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>
    

    您可以通过添加包含内容的子项来修复它,例如简单空间 . 但我们都讨厌为什么是设计问题添加空间 . 因此,使用 white-space 属性伪造内容 .

    <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>
    

    position: relative; 确保修复的正确定位 . 并且 white-space: pre; 使您无需在修复中添加任何内容(如空白区域) . height: 0px;width: 0px;overflow: hidden; 确保你永远不会看到修复 .

    您可能需要添加 line-height: 0px;max-height: 0px; 以确保在古老的IE浏览器中高度实际为零(我不确定) . 如果它不起作用,你可以选择在旧的IE浏览器中添加 <!--dummy--> .

    简而言之,您只需使用CSS即可完成所有这些操作(无需将实际子项添加到HTML DOM树中):

    <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

    如果合适,使用 top 而不是 margin-top 是另一种可能的解决方案 .

  • 0

    为了防止"Div parent"使用"div child"的保证金:
    在父母使用这些CSS:

    • 漂浮

    • 填充

    • 边界

    • 溢出

相关问题