负边距不会拉起 Firefox 中浮动的兄弟姐妹
Negative margin does not pull up floated siblings in Firefox
我有一个框,其中包含一个标题和另外两个框。标题的顶部边距为负,因此它呈现在框外。在除 Firefox 之外的所有浏览器中,标题都会正确拉出其同级框,但在 Firefox 中,框会保留在原位。
如果我从方框中移除浮标,但它们会 向上移动。除了给盒子负数 margin-top 之外,还有解决这个问题的方法吗?
div {
background: red;
padding: 2rem;
margin-top: 8rem;
box-sizing: border-box;
}
div:after {
display: table;
content: "";
clear: both;
}
div div {
background: green;
margin: 0 0 2rem;
width: 45%;
float: left; /* Remove this and float: right below and it works in FF */
}
div div + div {
float: right;
}
h2 {
margin-top: -8rem;
}
<div>
<h2>
Hello
</h2>
<div>
These boxes also render outside the red one.
</div>
<div>
In every browser except Firefox.
</div>
</div>
这取决于块结构在浏览器中的计算方式。我通过用 top
和 position
属性
替换 margin-top
来解决它
div {
background: red;
padding: 2rem;
margin-top: 8rem;
box-sizing: border-box;
}
div:after {
display: table;
content: "";
clear: both;
}
div div {
position: relative;
top: -12rem;
background: green;
width: 45%;
float: left;
/* Remove this and float: right below and it works in FF */
}
div div + div {
float: right;
}
h2 {
margin-top: -8rem;
position: absolute;
}
工作fiddle:https://jsfiddle.net/nobalmohan/6sjhy1q3/
我相信,还有其他方法可以解决这个问题。
您可以将浮动框包裹在非浮动容器中。
(注意:我给了每个 div 自己的 class 只是为了更清楚地说明哪些样式适用于哪些 div。)
.d1 {background:red; padding:2rem; margin-top:8rem; box-sizing:border-box;}
.d1:after {display:table; content:""; clear:both;}
.d3 {float:left; background:green; padding:2rem; box-sizing:border-box; width:45%;}
.d3 + .d3 {float:right;}
h2 {margin-top:-8rem;}
<div class="d1">
<h2>Hello</h2>
<div class="d2">
<div class="d3">These boxes render outside the red one.</div>
<div class="d3">In every browser.</div>
</div>
</div>
首先我进一步简化为下面的最小示例:
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
background: red;
padding: 2rem;
margin-top: 8rem;
}
.wrapper > div {
background: green;
padding: 2rem;
float:left;
}
.wrapper:after{
content: '';
clear:both;
display: table;
}
h2 {
margin-top: -8rem;
}
<div class="wrapper">
<h2>Hello</h2>
<div>These boxes also render outside the red one.</div>
</div>
为什么会这样?
首先尝试从 wrapper
中删除 padding
,看看现在 margin collapsing 会发挥作用,甚至在 Firefox 中也会显示相同的行为。 (wrapper
的 padding: 2rem
防止 h2
的边距与 wrapper
重叠)。很明显 margin collpasing 在这里没有作用。
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
background: red;
margin-top: 8rem;
}
.wrapper > div {
background: green;
padding: 2rem;
float:left;
}
.wrapper:after{
content: '';
clear:both;
display: table;
}
h2 {
margin-top: -8rem;
}
<div class="wrapper">
<h2>Hello</h2>
<div>These boxes also render outside the red one.</div>
</div>
现在尝试为 wrapper
中的 div 切换 float: left
,您会看到 Floated 容器有问题负边距(在 Firefox 中)。
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
background: red;
padding: 2rem;
margin-top: 8rem;
}
.wrapper > div {
background: green;
padding: 2rem;
}
.wrapper:after{
content: '';
clear:both;
display: table;
}
h2 {
margin-top: -8rem;
}
<div class="wrapper">
<h2>Hello</h2>
<div>These boxes also render outside the red one.</div>
</div>
所以这是一个错误?
文档只是这样说:
Negative values for margin properties are allowed, but there may be
implementation-specific limits.(Source: W3C)
而且 Firefox 似乎有一个针对它的旧错误,我猜它仍然打开 - 参见 this Bugzilla link
。
解决方案
不要让具有负边距的容器的 浮动 兄弟姐妹:
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
background: red;
padding: 2rem;
margin-top: 8rem;
}
.wrapper > .float-wrap > div {
background: green;
padding: 2rem;
float:left;
}
.wrapper > .float-wrap:after{
content: '';
clear:both;
display: table;
}
h2 {
margin-top: -8rem;
}
<div class="wrapper">
<h2>Hello</h2>
<div class="float-wrap">
<div>These boxes also render outside the red one.</div>
</div>
</div>
所以这是包装 浮动容器 的代码的解决方案:
div {
background: red;
padding: 2rem;
margin-top: 8rem;
box-sizing: border-box;
}
div:after {
display: table;
content: "";
clear: both;
}
div > div > div {
background: green;
margin: 0 0 2rem;
width: 45%;
float: left;
}
div > div > div + div {
float: right;
}
h2 {
margin-top: -8rem;
}
div > h2 + div {
padding: 0;
margin: 0;
background: none;
}
<div>
<h2>Hello</h2>
<div>
<div>
These boxes also render outside the red one.
</div>
<div>
In every browser except Firefox.
</div>
</div>
</div>
我认为这可能是除 Firefox 之外的所有浏览器中的错误。
The Working Draft Collapsing Margin Spec states:
- Margins of a floated box do not collapse with any other margins.
- If a box is collapsed through and it has clearance applied to one of the collapsed margins, then those margins do not collapse with certain of the parent's margins: If clearance is applied to, respectively, the top, right or left margin, then those margins do not collapse with the parent's bottom, left or right margin, respectively.
似乎大多数浏览器,除了 Firefox,都错误地允许浮动的 div 边距折叠。但是,通过将 clear
属性 设置为 div div
css 将导致浮动保留在其容器中(请参见下面的代码片段)。此行为更符合规范的规定。
The Recommendation for positioning of floats 也让我相信您在其他浏览器中看到的可能不是您想要的结果。规范建议似乎表明浮动项应始终位于其父容器内,除非另有特别说明。
A floating box's outer top may not be higher than the top of its containing block.
演示向浮动添加清理将使它们包含在其父级中
div {
background: red;
padding: 2rem;
margin-top: 8rem;
box-sizing: border-box;
}
div:after {
display: table;
content: "";
clear: both;
}
div div {
background: green;
margin: 0 0 2rem;
width: 45%;
float: left;
clear:right; // Adding this causes the floats to stay in their container
}
div div + div {
float: right;
}
h2 {
margin-top: -8rem;
}
<div>
<h2>
Hello
</h2>
<div>
These boxes also render outside the red one.
</div>
<div>
In every browser except Firefox.
</div>
</div>
我有一个框,其中包含一个标题和另外两个框。标题的顶部边距为负,因此它呈现在框外。在除 Firefox 之外的所有浏览器中,标题都会正确拉出其同级框,但在 Firefox 中,框会保留在原位。
如果我从方框中移除浮标,但它们会 向上移动。除了给盒子负数 margin-top 之外,还有解决这个问题的方法吗?
div {
background: red;
padding: 2rem;
margin-top: 8rem;
box-sizing: border-box;
}
div:after {
display: table;
content: "";
clear: both;
}
div div {
background: green;
margin: 0 0 2rem;
width: 45%;
float: left; /* Remove this and float: right below and it works in FF */
}
div div + div {
float: right;
}
h2 {
margin-top: -8rem;
}
<div>
<h2>
Hello
</h2>
<div>
These boxes also render outside the red one.
</div>
<div>
In every browser except Firefox.
</div>
</div>
这取决于块结构在浏览器中的计算方式。我通过用 top
和 position
属性
margin-top
来解决它
div {
background: red;
padding: 2rem;
margin-top: 8rem;
box-sizing: border-box;
}
div:after {
display: table;
content: "";
clear: both;
}
div div {
position: relative;
top: -12rem;
background: green;
width: 45%;
float: left;
/* Remove this and float: right below and it works in FF */
}
div div + div {
float: right;
}
h2 {
margin-top: -8rem;
position: absolute;
}
工作fiddle:https://jsfiddle.net/nobalmohan/6sjhy1q3/
我相信,还有其他方法可以解决这个问题。
您可以将浮动框包裹在非浮动容器中。 (注意:我给了每个 div 自己的 class 只是为了更清楚地说明哪些样式适用于哪些 div。)
.d1 {background:red; padding:2rem; margin-top:8rem; box-sizing:border-box;}
.d1:after {display:table; content:""; clear:both;}
.d3 {float:left; background:green; padding:2rem; box-sizing:border-box; width:45%;}
.d3 + .d3 {float:right;}
h2 {margin-top:-8rem;}
<div class="d1">
<h2>Hello</h2>
<div class="d2">
<div class="d3">These boxes render outside the red one.</div>
<div class="d3">In every browser.</div>
</div>
</div>
首先我进一步简化为下面的最小示例:
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
background: red;
padding: 2rem;
margin-top: 8rem;
}
.wrapper > div {
background: green;
padding: 2rem;
float:left;
}
.wrapper:after{
content: '';
clear:both;
display: table;
}
h2 {
margin-top: -8rem;
}
<div class="wrapper">
<h2>Hello</h2>
<div>These boxes also render outside the red one.</div>
</div>
为什么会这样?
首先尝试从
wrapper
中删除padding
,看看现在 margin collapsing 会发挥作用,甚至在 Firefox 中也会显示相同的行为。 (wrapper
的padding: 2rem
防止h2
的边距与wrapper
重叠)。很明显 margin collpasing 在这里没有作用。* { box-sizing: border-box; } body { margin: 0; } .wrapper { background: red; margin-top: 8rem; } .wrapper > div { background: green; padding: 2rem; float:left; } .wrapper:after{ content: ''; clear:both; display: table; } h2 { margin-top: -8rem; }
<div class="wrapper"> <h2>Hello</h2> <div>These boxes also render outside the red one.</div> </div>
现在尝试为
wrapper
中的 div 切换float: left
,您会看到 Floated 容器有问题负边距(在 Firefox 中)。* { box-sizing: border-box; } body { margin: 0; } .wrapper { background: red; padding: 2rem; margin-top: 8rem; } .wrapper > div { background: green; padding: 2rem; } .wrapper:after{ content: ''; clear:both; display: table; } h2 { margin-top: -8rem; }
<div class="wrapper"> <h2>Hello</h2> <div>These boxes also render outside the red one.</div> </div>
所以这是一个错误?
文档只是这样说:
Negative values for margin properties are allowed, but there may be implementation-specific limits.(Source: W3C)
而且 Firefox 似乎有一个针对它的旧错误,我猜它仍然打开 - 参见 this Bugzilla link
。
解决方案
不要让具有负边距的容器的 浮动 兄弟姐妹:
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
background: red;
padding: 2rem;
margin-top: 8rem;
}
.wrapper > .float-wrap > div {
background: green;
padding: 2rem;
float:left;
}
.wrapper > .float-wrap:after{
content: '';
clear:both;
display: table;
}
h2 {
margin-top: -8rem;
}
<div class="wrapper">
<h2>Hello</h2>
<div class="float-wrap">
<div>These boxes also render outside the red one.</div>
</div>
</div>
所以这是包装 浮动容器 的代码的解决方案:
div {
background: red;
padding: 2rem;
margin-top: 8rem;
box-sizing: border-box;
}
div:after {
display: table;
content: "";
clear: both;
}
div > div > div {
background: green;
margin: 0 0 2rem;
width: 45%;
float: left;
}
div > div > div + div {
float: right;
}
h2 {
margin-top: -8rem;
}
div > h2 + div {
padding: 0;
margin: 0;
background: none;
}
<div>
<h2>Hello</h2>
<div>
<div>
These boxes also render outside the red one.
</div>
<div>
In every browser except Firefox.
</div>
</div>
</div>
我认为这可能是除 Firefox 之外的所有浏览器中的错误。
The Working Draft Collapsing Margin Spec states:
- Margins of a floated box do not collapse with any other margins.
- If a box is collapsed through and it has clearance applied to one of the collapsed margins, then those margins do not collapse with certain of the parent's margins: If clearance is applied to, respectively, the top, right or left margin, then those margins do not collapse with the parent's bottom, left or right margin, respectively.
似乎大多数浏览器,除了 Firefox,都错误地允许浮动的 div 边距折叠。但是,通过将 clear
属性 设置为 div div
css 将导致浮动保留在其容器中(请参见下面的代码片段)。此行为更符合规范的规定。
The Recommendation for positioning of floats 也让我相信您在其他浏览器中看到的可能不是您想要的结果。规范建议似乎表明浮动项应始终位于其父容器内,除非另有特别说明。
A floating box's outer top may not be higher than the top of its containing block.
演示向浮动添加清理将使它们包含在其父级中
div {
background: red;
padding: 2rem;
margin-top: 8rem;
box-sizing: border-box;
}
div:after {
display: table;
content: "";
clear: both;
}
div div {
background: green;
margin: 0 0 2rem;
width: 45%;
float: left;
clear:right; // Adding this causes the floats to stay in their container
}
div div + div {
float: right;
}
h2 {
margin-top: -8rem;
}
<div>
<h2>
Hello
</h2>
<div>
These boxes also render outside the red one.
</div>
<div>
In every browser except Firefox.
</div>
</div>