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

时间:2009-11-19 11:02:47

标签: css xhtml margin nested

我有一个div),其中包含另一个div孩子)。 Parent是body中第一个没有特定CSS样式的元素。当我设置

.child
{
    margin-top: 10px;
}

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

我的DOCTYPE设置为XHTML Transitional

我在这里缺少什么?

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

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

14 个答案:

答案 0 :(得分:429)

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

.parent { overflow: auto; }

或:

.parent { overflow: hidden; }

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

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

按热门请求更新 崩溃边缘的重点是处理文本内容。例如:

<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 contextoverflow或边距技巧会给你这个。

答案 1 :(得分:46)

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

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

.child {
    margin-top: 0;
}

.parent {
    padding-top: 10px;
}

答案 2 :(得分:19)

Although all of the answers fix the issue but they come with trade-offs/adjustments/compromises like

  • floats, You have to float elements
  • border-top, This pushes the parent at least 1px downwards which should then be adjusted with introducing -1px margin to the parent element itself. This can create problems when parent already has margin-top in relative units.
  • padding-top, same effect as using border-top
  • overflow: hidden, Can't be used when parent should display overflowing content, like a drop down menu
  • overflow: auto, Introduces scrollbars for parent element that has (intentionally) overflowing content (like shadows or tool tip's triangle)

The issue can be resolved by using CSS3 pseudo elements as follows

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

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

答案 3 :(得分:12)

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

答案 4 :(得分:7)

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

答案 5 :(得分:6)

这对我有用

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

.child {
margin-top:260px;
}

http://jsfiddle.net/97fzwuxh/

答案 6 :(得分:2)

我发现了, 在你的.css&gt;里面,如果你将div元素的显示属性设置为内联块,它就可以解决问题。保证金将按预期运作。

答案 7 :(得分:1)

margin中包含的.child元素正在崩溃。

<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。通过在margin-top#child超过16px,您会开始注意到它的位置移动。

答案 8 :(得分:1)

我也遇到过这个问题,但我更倾向于防止负边距黑客攻击,所以我放了一个

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

它周围都有填充而不是边距。当然这意味着更多的divitis,但它可能是最简洁的方法来做到这一点。

答案 9 :(得分:1)

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

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;

答案 10 :(得分:1)

在我知道正确答案之前我找到的替代解决方案是在父元素中添加透明边框

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

.parent {
    border:1px solid transparent;
}

答案 11 :(得分:1)

纯粹的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>

答案 12 :(得分:0)

如果合适,使用top代替margin-top是另一种可能的解决方案。

答案 13 :(得分:0)

防止&#34; Div父母&#34;使用&#34; div child&#34;的保证金:
在父母身上使用这些css:

  • 填充
  • 边界
  • 溢出