我有一个标题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;
}Run Code Online (Sandbox Code Playgroud)
<div id="header">
<h1>Title</h1>
<ul id="navbar"></ul>
</div>Run Code Online (Sandbox Code Playgroud)
dig*_*mer 33
我没有一个可靠的解释为什么会发生这种情况,但我通过更改top-marginto top-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
Run Code Online (Sandbox Code Playgroud)
Jes*_*era 16
这是避免父子元素之间边缘折叠的一些方法.使用与其他样式更好地匹配的那个:
display为其他block.float为其他none.padding.例如,如果你有margin-top: 10px,替换为padding-top: 10px;.position(absolute或relative)有属性top,bottom等等.例如,如果你有margin-top: 10px,请更换position: relative; top: 10px;.padding或a border到父元素.边框可以是1px和透明.overflow为除父元素之外visible的其他元素.我知道这是一个老问题,我遇到过很多次。问题是这里的所有修复都是可能会产生意外后果的黑客攻击。
首先,对根本问题有一个简单的解释。由于边距折叠的工作方式,如果容器内的第一个元素具有顶部边距,则该顶部边距会有效地应用于父容器本身。您可以通过执行以下操作自行测试:
<div>
<h1>Test</h1>
</div>
Run Code Online (Sandbox Code Playgroud)
在调试器中,打开它并将 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;
}
Run Code Online (Sandbox Code Playgroud)
有了这个,按照上面的标记示例,您将修改您的 div:
<div class="top-margin-fix">
<h1>Test</h1>
</div>
Run Code Online (Sandbox Code Playgroud)
为什么这样做?
容器中的第一个元素,如果它没有上边距,则设置下一个元素上边距的开始位置。通过添加:before伪元素,浏览器实际上在您的第一个元素之前向父容器添加了一个非语义(换句话说,有利于 SEO)的元素。
Q. 为什么高度:.0000001em?
A. 浏览器向下推边距元素需要一个高度。这个高度实际上为零,但它仍然允许您向父容器本身添加填充。由于它实际上为零,因此它也不会对容器的布局产生影响。美丽的。
现在你可以添加一个类(或者更好,在 SASS/LESS 中,一个 mixin!)来解决这个问题,而不是添加奇怪的显示样式,当你想对元素做其他事情时会导致意想不到的后果,有目的地消除元素的边距和/或用填充或奇怪的位置/浮动样式替换它,这些样式实际上并非旨在解决此问题。