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

.child
{
    margin-top: 10px;
}

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

我的DOCTYPE被设置为XHTML Transitional。

我错过了什么?

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

编辑2 这种行为在FF、IE和CR上都是一样的。


当前回答

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

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

.parent {
    border:1px solid transparent;
}

其他回答

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

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;通过浮动:左;

你可以通过在伪元素display: flex;给父母。

.parent:before {
  content: '';
  display: flex;
}

另一种方法是将父节点的display属性设置为flow-root。

.parent {
  display: flow-root;
}

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

您可以通过添加带有内容(例如简单空格)的子元素来修复它。但我们都不喜欢为设计问题添加空格。因此,可以使用空白属性来伪造内容。

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

其中位置:相对;确保固定的正确位置。和空格:pre;使您不必添加任何内容-如空白-到修复。和高度:0px;宽度:0px;溢出:隐藏;确保你永远都看不到解决办法。

你可能需要添加line-height: 0px;或者max-height: 0px;以确保高度实际上是零在古老的IE浏览器(我不确定)。还可以添加<!——dummy——>到旧的IE浏览器,如果它不工作。

简而言之,你可以用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>

边框解决方案很好,但不是最好的,因为它增加了元素的总宽度,即使是透明的

但是负边界宽度呢?不工作:(

但我们仍然可以用box-sizing属性来实现 使边界向负方向移动

.parent{
   border:5px solid transparent;
   box-sizing: border-box;
 }
.child{
   margin-top:5px; 
 }

注意,如果你想要10px的上边距,你必须只添加5px的边距,因为5px的上边距仍然会产生影响,这个原因是为了防止崩溃问题。

防止“Div父”使用“Div子”的边距: 在父级中使用这些css:

浮动 填充 边境 溢出