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

Margin on child element moves parent element

提问人:Robert Koritnik 提问时间:11/19/2009 最后编辑:Robert Koritnik 更新时间:1/23/2023 访问量:232896

问:

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

.child
{
    margin-top: 10px;
}

最终结果是,我的孩子的顶部仍然与父母保持一致。我的父母没有向下移动 10px,而是向下移动 10px。

My 设置为 。DOCTYPEXHTML Transitional

我在这里错过了什么?

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

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

嵌套 的 CSS XHTML 边距

评论

248赞 Muhammad Umer 3/14/2013
这种行为毫无意义。边距应该保留在父级内部。不移动父项。这些规则由谁编写。
20赞 Casey Dwayne 3/11/2014
+2 最后一条评论。说真的,这条规则让我很烦恼。“每次都有 60% 的时间有效”——这就是利润率。
44赞 erdomester 9/27/2014
我完全同意最后两位评论者的观点。这太疯狂了。有趣的是,在父项上添加一个 1px 的边框可以使其正常工作,但这意味着你有一个边框......如果这是预期的行为,那么这是荒谬的
1赞 Bhojendra Rauniyar 2/12/2016
这也可以帮助您:)stackoverflow.com/questions/35337043/......
9赞 Nolonar 12/15/2016
这让我想起了默认的箱子尺寸规则:“我们需要运送一个箱子。箱子不得大于 100 厘米。我们需要在盒子内填充 10 厘米的衬垫,以确保我们的内容在运输过程中不会破裂。让我们把盒子做成120厘米!真是个笑话。

答:

65赞 Ben James 11/19/2009 #1

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

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

.child {
    margin-top: 0;
}

.parent {
    padding-top: 10px;
}

评论

4赞 o.k.w 11/19/2009
为父项添加边框也会影响子项的边距,请尝试.parent {border: solid 1px;}
2赞 Brilliand 5/27/2011
边距不会增加填充...它单独适用。但视觉效果是一样的。
2赞 feeela 6/17/2011
如果你想要一个最高利润......?不是真正的解决方案。
4赞 Joey Morani 4/8/2012
就像 feeela 说的——如果需要最高利润,这并不是一个真正的解决方案。VDBOOR的答案更适合。
1赞 Slavik Meltser 3/9/2014
有很多解决方案,你只需要有足够的创造力。干杯。:-)
1赞 25thhour 11/19/2009 #2

其中包含的元素正在坍塌。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>

在此示例中,正在接收来自浏览器的默认样式。浏览器默认值通常为 16px。通过超过 16px 的设置,您开始注意到它的位置移动。pmarginfont-sizemargin-top#child

599赞 vdboor 12/21/2009 #3

DIV 中具有边距的子元素中找到替代项 您还可以添加:

.parent { overflow: auto; }

艺术

.parent { overflow: hidden; }

这样可以防止边距塌陷。边框和填充也是如此。 因此,您还可以使用以下方法来防止顶部边距崩溃:

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

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


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

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>

由于浏览器折叠了边距,因此文本将按预期显示,并且包装器标记不会影响边距。每个元素确保其周围有间距,但间距不会加倍。和的边距不会相加,而是相互滑动(它们折叠)。and 元素也会发生同样的情况。<div><h2><p><p><ul>

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

评论

54赞 Muhammad Umer 3/14/2013
我想知道为什么会这样,这对任何人都有什么好处。这个“功能”是什么样的情况。
4赞 vdboor 3/17/2013
@MuhammadUmer,这与文本内容有关。例如,一系列 、 不会以这种方式获得奇怪的间隙或“双倍”边距。<h2><p><ul>
7赞 Muhammad Umer 3/18/2013
你能举一些例子吗?假设我有 div 作为背景。其中有 h1、h2 和 p。现在我想将 h1 向下移动一点,这样它就不会靠近背景 div 的上边缘,但又不扩展 h1 元素本身。我认为增加顶部边距。这是显而易见的。但是当我这样做时,光荣的背景决定随之下降。这是一项功能。这对 h1、h2 和 p 之间的间距有何帮助。帮我看看你在说什么。
3赞 JL Griffin 10/29/2015
我希望它能增加更多的利润。利润率下降是迄今为止我开发生涯中最令人讨厌的事情。如果我用 ID 将 2 个 div 并排放置,则期望 2 个 div 从顶部 5 px 开始,它们之间为 20px,而不是从顶部开始 5 px,它们之间为 10px。如果我想在它们之间放置 10 像素,ID 已指定 .老实说,我希望我能制定一个根本规则来阻止所有保证金崩溃。我讨厌我必须将纸上的边距大小增加一倍才能让它们在屏幕上真正做我想做的事情。而这个最重要的东西......真是一场灾难margin: 5px 10px;margin: 5px 5px;
3赞 peterc 4/24/2021
这占用了我半天的时间,我认为这是一个很好的解释 smashingmagazine.com/2019/07/margins-in-css/...。 看起来像是另一种选择。display: flow-root
1赞 Zyl 4/7/2013 #4

我也有这个问题,但更愿意防止负利润率黑客攻击,所以我放了一个

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

在它周围,所有这些都有填充而不是边距。当然,这意味着更多的divitis,但这可能是正确完成这项工作的最干净的方法。

15赞 George SEDRA 7/23/2013 #5

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

评论

4赞 Pigalev Pavel 10/6/2013
是的,有时只有这样才能提供帮助......或者最好这样说: <div style='width:0;高度:0'>&nbsp;</格>
1赞 schellmax 7/15/2014 #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;

9赞 erdomester 9/27/2014 #7

这就是对我有用的东西

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

.child {
margin-top:260px;
}

http://jsfiddle.net/97fzwuxh/

1赞 lamplightdev 11/20/2014 #8

如果适用,使用 instead 是另一种可能的解决方案。topmargin-top

1赞 SandRock 1/8/2015 #9

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

不过,您的盒子将使用额外的像素......

.parent {
    border:1px solid transparent;
}
25赞 Атанас Димитров 4/8/2015 #10

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

30赞 Ejaz 6/15/2015 #11

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

  • floats你必须浮动元素
  • border-top,这会将父元素向下推至少 1px,然后应通过向父元素本身引入边距进行调整。当父级已经具有相对单位时,这可能会产生问题。-1pxmargin-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/

评论

1赞 Flimm 12/23/2015
margin-top: -1px似乎没有必要。但我喜欢这个。
4赞 NinjaFart 11/11/2016
实际上,两者似乎都没有必要。在 Chrome 中测试。但最好的解决方案。margin-top: -1pxheight: 0
0赞 Michael Giovanni Pumo 11/13/2017
此方法大多有效,但不会考虑容器中最后一个元素的下边距。溢出不是平等的修复:隐藏;例如。
1赞 Ejaz 11/13/2017
@MichaelGiovanniPumo,可以使用以下方法修改答案以使用最后一个元素的下边距.parent:after...
0赞 fgblomqvist 10/18/2018
这绝对是当今的正确答案。完美无缺(之后和之前都戴上),我希望人们敢于滚动浏览其他的!
2赞 vincent thorpe 5/14/2016 #12

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

3赞 Yeti 11/13/2017 #13

简洁的纯 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+。这适用于任何现代浏览器(请注意较新的浏览器,IE8 不支持)。::before

上下文

如果元素的第一个子元素具有 ,则父元素将调整其位置,以折叠冗余边距。为什么?就是这样。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;

您可能需要添加或确保在古代 IE 浏览器中高度实际上为零(我不确定)。或者,如果它不起作用,您可以在旧的 IE 浏览器中添加它。line-height: 0px;max-height: 0px;<!--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赞 Yeti 9/12/2018
只有在你绝望的情况下才使用此解决方案,并且你不能为现有元素设置任何自定义 CSS - 否则使用真正的解决方案:为父元素设置。overflow: hidden;
5赞 bingo 3/11/2018 #14

要防止“Div parent”使用“div child”的边距: 在 parent 中使用以下 css:

  • 填充
  • 边境
  • 溢出
3赞 Hyzyr 10/27/2021 #15

播放父项的显示

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

.parent{ display: flex; }
1赞 Andreas Riedmüller 12/17/2022 #16

您可以通过向父元素添加伪元素来解决此问题。:beforedisplay: flex;

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

另一种方法是将父级的属性设置为 。displayflow-root

.parent {
  display: flow-root;
}
0赞 Ayman Morsy 1/20/2023 #17

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

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

但我们仍然可以实现它,迫使边界走向负面方向box-sizing property

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

请注意,如果您想要,则必须添加,因为顶部仍然影响,这是防止崩溃问题的原因。10px top margin5px margin5px border

2赞 Domske 1/23/2023 #18

这是关于保证金崩溃的。

块的边距和边距有时会合并(折叠)成一个边距,其大小是单个边距中最大的一个边距(如果它们相等,则仅是其中一个边距),这种行为称为边距折叠

根据具体情况,有几种解决方案。 一种解决方案是更改孩子的显示模式。

.child {
  display: inline-block;
}

也很高兴知道。边距折叠不适用于 flex 或 gird 容器。

.parent {
  display: flex;
  flex-direction: column;
}

或者与父母而不是孩子一起工作。更改或属性也可能有所帮助。或者绝对。这取决于您的布局。paddingmarginoverflowfloatposition

评论

0赞 Simon_Weaver 2/24/2023
所以这就像负利润率崩溃一样?