边距顶部将外部div向下推


126

我有一个头div作为包装div中的第一个元素,但是当我在头div内的h1中添加顶部边距时,它将整个头div向下推。我意识到,只要我在页面上的第一个可见元素上应用上边距,就会发生这种情况。

这是一个示例代码片段。谢谢!

div#header{
	width: 100%;
	background-color: #eee;
	position: relative;
}

div#header h1{
	text-align: center;
	width: 375px;
	height: 50px;
	margin: 50px auto;
	font-size: 220%;
	background: url('../../images/name_logo.png') no-repeat;
}
<div id="header">
	<h1>Title</h1>
	<ul id="navbar"></ul>
</div>

Answers:


193

放入overflow:auto父级,div
在此链接中查看更多


29
overflow:hidden在90%的情况下效果更好。
vsync

1
为什么溢出:隐藏会更好?
peterchon

5
@peterchon -因为汽车可能会导致滚动条
垂直同步

3
不再工作,通过@ SW4在此链接中的答案更好
am05mhz15年

1
overflow: hiddenoverflow: auto可能会导致不良的副作用,其中有些您可能不会一眼看到。我发现更改marginpadding可以解决问题,如下面的答案所示。仍然不明白为什么整个问题都会发生。
吉拉德·巴纳

34

对于发生这种情况的原因,我没有明确的解释,但已通过更改top-margintop-padding或添加display: inline-block到元素样式来解决。

编辑:这是我的理论

我觉得它与边距的塌陷(合并)有关。

来自W3C崩溃边际

在本规范中,表述塌陷边距是指两个或多个框(可能彼此相邻或嵌套)的相邻边距(没有非空内容,填充或边框区域或间隙将它们隔开)组合形成一个边距。

我的理论是,由于您的第一个元素在主体附近,因此两个边距合并并应用到主体:这将迫使主体的内容从所应用的折叠边距开始低于框模型

在某些情况下,边距不会倒塌,这可能值得一试(来自“倒塌边距”):

* floated elements
* absolutely positioned elements
* inline-block elements
* elements with overflow set to anything other than visible (They do not collapse margins with their children.)
* cleared elements (They do not collapse their top margins with their parent block’s bottom margin.)
* the root element

3
同样,在边缘已折叠的元素(内部元素)上的填充或边框也将使其不折叠。
匿名

这对我有用-我的容器中有绝对元素(下拉菜单),因此overflow:auto不起作用。
mwilcox

17

这是避免父子元素之间的边距崩溃的一些方法。使用适合您其余样式的样式:

  • 设置display为以外的其他值block
  • 设置float为以外的其他值none
  • 删除边距,然后改用padding。例如,如果有margin-top: 10px,则替换为padding-top: 10px;
  • 取出保证金,而是使用positionabsoluterelative)有属性topbottom等等。例如,如果你有margin-top: 10px,请更换position: relative; top: 10px;
  • 在边距崩溃的一侧添加一个padding或一个border元素。边框可以是1px且透明。
  • 设置overflow为除元素以外visible的其他值。

5

我知道这是一个老问题,我已经遇到过很多次了。问题在于,这里的所有修补程序都是可能会带来意想不到的后果的黑客。

首先,有一个简单的根本问题解释。由于边距折叠的工作方式,如果容器内的第一个元素具有顶部边距,则该顶部边距将有效地应用于父容器本身。您可以通过以下操作自行测试:

<div>
    <h1>Test</h1>
</div>

在调试器中,将其打开并悬停div。您会注意到div本身实际上位于H1元素的上边距停止的位置。此行为是浏览器所预期的。

因此,可以轻松地解决此问题,而不必求助于奇怪的黑客攻击,就像这里的大多数帖子一样(没有侮辱性,这只是事实)-只需回到原始说明即可...if the first element inside a container has a top margin...--接下来,您需要容器中的第一个元素没有上边距。好的,但是如何在不添加不会在语义上干扰文档的元素的情况下做到这一点呢?

简单!伪元素!您可以通过类或预定义的mixin来实现。添加一个:before伪元素:

通过类的CSS:

.top-margin-fix:before {   
    content: ' ';
    display: block;
    width: 100%;
    height: .0000001em;
}

这样,在上面的标记示例之后,您将像这样修改div:

<div class="top-margin-fix">
    <h1>Test</h1>
</div>

为什么这样做?

容器中的第一个元素(如果没有上边距)将设置下一个元素的上边距的开始位置。通过添加:before伪元素,浏览器实际上第一个元素之前将非语义元素(换句话说,对SEO有利)添加到父容器中。

问:为什么高度:.0000001em?

答:浏览器向下推边距元素所需的高度。该高度实际上为零,但仍然允许您向​​父容器本身添加填充。由于它实际上是零,因此它也不会影响容器的布局。美丽。

现在,您可以添加一个类(或者更好的是,在SASS / LESS中,一个mixin!)来解决此问题,而不是添加怪异的显示样式,当您要对元素执行其他操作时,这会导致意外的结果,目的是消除元素的边距和/或将其替换为实际上不打算解决此问题的填充或奇怪的位置/浮动样式。


2
.0000001em在IE11中真的舍入为零,从而破坏了您的解决方案。当我将其更改为.01em时,它可以工作。
Esger

1
我认为0.01em就足以仍然有效地为零。好点子。从好的方面来看,现在是2018年,我们许多人很快就会放弃对IE11的支持,尤其是在最近宣布MS将会再次构建新的浏览器(这次除外,基于铬,这意味着-从理论上讲) -不会完全糟透了。:D
dudewad

2

display: flex在这种情况下将起作用。给父元素display: flex;,然后根据您的要求给h1标签边距。


0

今天遇到这个问题。

overflow: hidden 当我跟随更多元素时,它没有按预期工作。

因此,我尝试更改父div的display属性并display: flex工作!

希望这可以帮助某人。:)


0

在父元素顶部添加少量填充可以解决此问题。

.parent{
  padding-top: 0.01em;
}

如果您需要父级内部的元素在父级元素外部可见,例如在创建重叠效果时,这很有用。


0

发生这种情况是由于利润率下降。当子元素接触父元素的边界,并且其中的任何一个都带有边距时,则:

  1. 最大的保证金将获胜(应用)。

  2. 如果它们中的任何一个有保证金,那么两者将共享相同的利润。

解决方案

  1. 将边框应用于父对象,使父子对象分离。
  2. 对父级应用填充,使父级和子级分开。
  3. 应用溢出而不是在父级上可见。
  4. 在父div中创建虚拟元素之前或之后使用,这可能会导致子元素和父元素的边距有所不同。
  5. 在应用边距的孩子和父母之间创建一个html元素也可以将它们分开。
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.