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

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

.child
{
margin-top: 10px;
}

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

我的DOCTYPE被设置为XHTML Transitional

我错过了什么?

< p > 编辑1 < br > 我的父母需要有严格定义的尺寸,因为它有一个背景,必须显示在它下面从上到下(像素完美)。因此,在它上设置垂直边距是没有去.

< p > 编辑2 < br > 这种行为在FF, IE和CR上是一样的
216196 次浏览

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

为了得到你想要的行为,你需要:

.child {
margin-top: 0;
}


.parent {
padding-top: 10px;
}

.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上有一个超过16px的margin-top,你开始注意到它的位置移动。

在div中具有边距的子元素找到了一个替代方法,你也可以添加:

.parent { overflow: auto; }

或者:

.parent { overflow: hidden; }

这个参数防止了崩溃的页边距。边框和填充也是如此。 因此,您还可以使用以下方法来防止上边际崩溃:

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

2021年更新:如果你愿意放弃IE11支持,你也可以使用新的CSS结构display: flow-root。有关块格式化上下文的全部细节,请参阅MDN Web文档


根据流行请求更新: 缩边距的全部意义在于处理文本内容。例如:< / p >

h1, h2, p, ul {
margin-top: 1em;
margin-bottom: 1em;
outline: 1px dashed blue;
}


div { outline: 1px solid red; }
<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中被称为新的块格式化上下文overflow或margin技巧会给你这个。

我也有这个问题,但更喜欢防止负利润率黑客,所以我放了一个

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

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

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

有趣的是,这里没有提到我最喜欢的解决方案:使用浮动。

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

注意,如果你需要父节点上的动态高度,它也必须是浮动的,所以只需用float:left;替换height:100px;

这对我来说很管用

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


.child {
margin-top:260px;
}

http://jsfiddle.net/97fzwuxh/

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

在我知道正确答案之前,我找到了另一个解决方案,即在父元素中添加透明边界

你的盒子将使用额外的像素…

.parent {
border:1px solid transparent;
}

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

虽然所有的答案都解决了问题,但它们都伴随着权衡/调整/妥协,比如

  • floats,你浮动元素
  • border-top,这将父元素向下推至少1px,然后应该通过向父元素本身引入-1px边距来进行调整。当父类已经在相对单位中有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/

我发现, 如果你将div元素的显示属性设置为inline-block,就可以解决这个问题。

.

.

纯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>
为了防止“Div父”使用“Div子”的边距:
在父级中使用这些css:

  • 浮动
  • 填充
  • 边境
  • 溢出

玩父母显示

.parent{
display: inline-block;
width: 100%;
}

.parent{ display: flex; }