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


414

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

.child
{
    margin-top: 10px;
}

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

DOCTYPE的设定为XHTML Transitional

我在这里想念什么?

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

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


188
这种行为毫无意义。保证金应留在父母一方。不动父母。谁编写这些规则。
穆罕默德·乌默尔2013年

10
+2为最后评论。这个规则严重困扰着我。“每次都有60%的时间都可以工作”-这就是利润。
Casey Dwayne 2014年

29
我完全同意最后两个评论者。疯了吧。有趣的是,向父级添加1px边框使其正常工作,但是,这意味着您具有边框...如果这是预期的行为,那么这是荒谬的
erdomester 2014年


5
这让我想起了默认的包装大小规则:“ 我们需要运送一个盒子。盒子不能大于100cm。我们需要在盒子内部留出10cm的填充物,以确保我们的内容在运输过程中不会破裂。盒子120厘米! “真是笑话。
Nolonar '16

Answers:


492

子元素中找到了替代项,并在DIV中留有边距您还可以添加:

.parent { overflow: auto; }

要么:

.parent { overflow: hidden; }

这样可以防止边距崩溃。边框和填充相同。因此,您还可以使用以下内容来防止利润暴跌:

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

根据受欢迎的要求进行更新:页 边空白的全部要点是处理文本内容。例如:

h1, h2, p, ul {
  margin-top: 1em;
  margin-bottom: 1em;
}
<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或保证金招会给你的。


41
我想知道为什么会这样对任何人有好处。这个“功能”本意是什么情况。
穆罕默德·乌默尔

2
@MuhammadUmer,这与文本内容有关。例如,一个系列的<h2><p><ul>不会得到奇怪的差距或“双”利润这种方式。
vdboor 2013年

7
你能举个例子吗?假设我有div作为背景。包含h1,h2和p。现在,我想将h1向下移动一点,以便它离背景div的上边缘不太近,但不扩展h1元素本身。我想增加最高利润。这是显而易见的。但是当我这样做时,辉煌的背景决定随之而来。这是什么功能。这如何帮助h1,h2和p之间的间距。帮我看看你在说什么。
Muhammad Umer

1
我为您添加了一个示例
vdboor 2015年

3
我希望它会增加更多的利润。迄今为止,利润下降是我发展生涯中最烦人的事情。如果我将2个div与margin: 5px 10px;ID 彼此相邻,则期望2个div从顶部开始5 px,在它们之间20 px,而不是从顶部5 px和它们之间的10 px。如果我想在它们之间指定10像素,则id已指定margin: 5px 5px;。老实说,我希望有一个根本的规则可以阻止所有保证金崩溃。我讨厌我必须将纸张上的页边距扩大一倍,以使它们实际执行我在屏幕上想要的功能。以及这件最重要的事情……真是一场灾难
JL Griffin

50

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

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

.child {
    margin-top: 0;
}

.parent {
    padding-top: 10px;
}

3
为父母添加边框也会影响孩子的边缘,请尝试.parent {border: solid 1px;}
okw

1
边距不会添加到填充中...它是单独应用的。但是视觉效果是相同的。
Brilliand

1
如果您想获得最高利润呢?并不是真正的解决方案。
Feeela 2011年

3
如Feeela所说-如果需要最高利润,这并不是真正的解决方案。vdboor的答案更适合。
乔伊·莫拉尼

1
有很多解决方案,您只需要足够的创意即可。干杯。:-)
Slavik Meltser 2014年

23

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

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


margin-top: -1px似乎没有必要。但是我喜欢这样。
Flimm 2015年

3
实际上,两者margin-top: -1pxheight: 0没有必要。在Chrome中测试。但是最好的解决方案。
NinjaFart '16

此方法通常有效,但不会考虑容器中最后一个元素的底边距。这不是溢出的等同解决方案:例如。
Michael Giovanni Pumo's

1
@MichaelGiovanniPumo答案可以通过修改与最后一个元素的下边距工作.parent:after...
埃贾兹

如今,这绝对是正确的答案。可以完美地工作(在前后都可以使用),我希望人们敢于超越其他人!
fgblomqvist


9

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


2
是的,有时只有这样才能有所帮助...或更好地输入以下内容:<div style ='width:0; height:0'>&
divbs


2

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


2

整洁的纯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+。这将在任何现代浏览器中都可以使用(请注意::beforeIE8不支持的更新版本)。

语境

如果元素的第一个子元素有个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浏览器中高度实际上为零(我不确定)。<!--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>

仅在绝望的情况下才使用此解决方案,并且不能为现有元素设置任何自定义CSS-否则请使用真正的解决方案:overflow: hidden;为父级设置。
雪人

2

为了防止“父级父级”使用“ div子级”的边距:
在父级中使用以下CSS:

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

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大于16像素的像素,#child您开始注意到它的位置移动。


1

我也遇到了这个问题,但更希望防止出现负利润黑客攻击,因此我提出了

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

周围都有填充而不是边距。当然,这意味着更多的神经,但这可能是正确完成此操作的最干净的方法。


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;


1

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

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

.parent {
    border:1px solid transparent;
}

0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.