472

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

.child
{
    margin-top: 10px;
}

最终结果是我孩子的顶部仍然与父母对齐。我的父母没有将孩子向下移动 10 像素,而是向下移动了 10 像素。

DOCTYPE的设置为XHTML Transitional.

我在这里想念什么?

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

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

4

15 回答 15

562

在具有 DIV 内边距的子元素中找到了替代方法您还可以添加:

.parent { overflow: auto; }

或者:

.parent { overflow: hidden; }

这可以防止边距塌陷。边框和填充做同样的事情。因此,您还可以使用以下方法来防止上边距崩溃:

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

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


应大众要求更新: 折叠边距的全部意义在于处理文本内容。例如:

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>不会相加,但会相互滑入(它们会塌陷)。and元素<p>也是如此。<ul>

可悲的是,对于现代设计,当您明确想要一个容器时,这个想法可能会咬住您。这在 CSS speak中称为新的块格式化上下文。overflowor 保证金技巧会给你。

于 2009-12-21T13:00:03.920 回答
59

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

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

.child {
    margin-top: 0;
}

.parent {
    padding-top: 10px;
}
于 2009-11-19T11:10:31.413 回答
28

尽管所有答案都解决了问题,但它们带有权衡/调整/妥协,例如

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

于 2015-06-15T14:22:06.967 回答
19

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

于 2015-04-08T09:36:53.160 回答
10

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

于 2013-07-23T09:00:13.990 回答
9

这对我有用

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

.child {
margin-top:260px;
}

http://jsfiddle.net/97fzwuxh/

于 2014-09-26T18:34:32.373 回答
5

为了防止“div parent”使用“div child”的边距:
在 parent 中使用这些 css:

  • 漂浮
  • 填充
  • 边界
  • 溢出
于 2018-03-11T06:00:47.693 回答
3

整洁的纯 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>

Whereposition: relative;确保正确定位修复。并且white-space: pre;使您不必在修复中添加任何内容(例如空格)。并height: 0px;width: 0px;overflow: hidden;确保您永远不会看到修复程序。

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

简而言之,您可以仅使用 CSS 完成所有这些操作(无需向 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>
于 2017-11-13T09:30:00.430 回答
2

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

于 2016-05-13T22:29:47.367 回答
2

玩父母的显示

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

或者

.parent{ display: flex; }
于 2021-10-27T06:50:35.363 回答
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>

在这个例子中,pmargin从浏览器接收默认样式。浏览器默认font-size值通常为 16 像素。通过margin-top超过 16 像素,#child您开始注意到它的位置移动。

于 2009-11-19T11:45:40.417 回答
1

在我知道正确答案之前,我发现的另一种解决方案是为父元素添加透明边框。

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

.parent {
    border:1px solid transparent;
}
于 2015-01-08T09:09:07.530 回答
1

I had this problem too but preferred to prevent negative margins hacks, so I put a

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

around it all which has paddings instead of margins. Of course this means more divitis but it's probably the cleanest way to do get this done properly.

于 2013-04-07T15:03:51.260 回答
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;

于 2014-07-14T20:13:54.497 回答
0

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

于 2014-11-20T10:57:32.520 回答