CSS margin-top 不能使用 clear:两者
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4198269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
margin-top not working with clear: both
提问by Vishal
<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="clear: both; margin-top: 200px;">Main Data</div>
Why is the margin:top
for 'Main Data' not working in the code above?
为什么margin:top
“主数据”在上面的代码中不起作用?
采纳答案by Pointy
You could put the two floated divs into anotherone that's got "overflow: hidden" set:
您可以将两个浮动的 div 放入另一个设置了“溢出:隐藏”的div 中:
<div style='overflow:hidden'>
<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
</div>
<div style="clear: both; margin-top: 200px;">Main Data</div>
edit— To add a bit to this 5-year-old answer: I think the cause of the confusing behavior is the somewhat complicated process of margin collapse. A good trick with the original HTML from the OP is to add a CSS rule like this:
编辑- 为这个 5 年前的答案添加一点:我认为造成混乱行为的原因是margin collapse的一些复杂过程。使用来自 OP 的原始 HTML 的一个好技巧是添加这样的 CSS 规则:
div { border: 1px solid transparent; }
Poof! Now (without my additional <div>
) it works fine! Well, except for that extra pixel from the borders. In particular, I thinkit's a combination of the way that clear: both
works and the margin collapse rules that result in the unexpected layout from the code in the OP.
噗!现在(没有我的附加<div>
)它工作正常!好吧,除了边框的额外像素。特别是,我认为这是clear: both
工作方式和边距折叠规则的结合,导致 OP 中的代码出现意外布局。
edit again— For the complete (and, I think, completely accurate) story, see Mark Amery's excellent answer. The details have some complexity that this answer glosses over.
再次编辑——有关完整(我认为,完全准确)的故事,请参阅Mark Amery 的出色回答。细节有一些复杂性,这个答案掩盖了。
回答by Randall Cook
While Pointy shows how you can wrap the floats in a div, alternatively you can insert an empty div between the floats and the main data section. For example:
虽然 Pointy 展示了如何将浮点数包装在 div 中,但您也可以在浮点数和主数据部分之间插入一个空的 div。例如:
<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="clear: both;"></div>
<div style="margin-top: 200px;">Main Data</div>
This might prove useful in cases where adding a div wrapper around some HTML is not desirable.
在不希望在某些 HTML 周围添加 div 包装器的情况下,这可能会被证明是有用的。
回答by Mark Amery
The logic behind this in the spec is mind-bending, and involves a complicated interaction of the rules for clearanceand collapsing margins.
规范中这背后的逻辑令人费解,并且涉及清除和折叠边距规则的复杂交互。
You're probably familiar with the conventional CSS box model, in which the content boxis contained within a padding boxcontained within a border boxcontained within a margin box:
您可能熟悉传统的 CSS框模型,其中内容框包含在边距框内的边框框内的内边距框内:
For elements with clear
set to something other than none
, an additional component may be introduced to this model: clearance.
对于clear
设置为 以外的其他元素的元素,none
可能会在此模型中引入一个附加组件:clearance。
Values other than 'none' potentially introduce clearance. Clearance inhibits margin collapsing and acts as spacing above the margin-top of an element.
'none' 以外的值可能会引入clear。间隙会抑制边距折叠并充当元素顶部边距上方的间距。
In other words, the box model in those cases really looks more like this:
换句话说,这些情况下的盒模型看起来更像这样:
But when is clearance introduced, and how big should it be? Let's start with the first of those questions. The spec says:
但是什么时候引入清关,应该有多大?让我们从第一个问题开始。规范说:
Computing the clearance of an element on which 'clear' is set is done by first determining the hypothetical position of the element's top border edge. This position is where the actual top border edge would have been if the element's 'clear' property had been 'none'.
If this hypothetical position of the element's top border edge is not past the relevant floats, then clearance is introduced, and margins collapse according to the rules in 8.3.1.
计算设置了“clear”的元素的间隙是通过首先确定元素顶部边界边缘的假设位置来完成的。如果元素的“clear”属性为“none”,则此位置是实际的顶部边框边缘所在的位置。
如果元素的顶部边框边缘的这个假设位置没有超过相关的浮动,则引入间隙,并根据 8.3.1 中的规则折叠边距。
Let's apply this logic to the question asker's code. Remember, we're trying to explain the position of the third div in the code below (backgrounds added to aid in visualisation):
让我们将此逻辑应用于提问者的代码。请记住,我们试图在下面的代码中解释第三个 div 的位置(添加背景以帮助可视化):
<div style="float: left; background: red;">Left</div>
<div style="float: right; background: green;">Right</div>
<div style="clear: both; margin-top: 200px; background: blue;">Main Data</div>
Let us imagine, as the spec asks us to, that clear
is set to none
on the third div, instead of both
. Then what would the snippet above look like?
让我们想象一下,正如规范要求我们那样,它clear
被设置none
在第三个 div 上,而不是both
。那么上面的代码片段会是什么样子呢?
<div style="float: left; background: red;">Left</div>
<div style="float: right; background: green;">Right</div>
<div style="clear: none; margin-top: 200px; background: blue;">Main Data</div>
Here, the third div is overlappingthe two floated divs. But wait; why is this so? Sure, it's allowable for floated elements to overlap block-level ones (per the Floats spec, "Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float did not exist."), but our third div has loads of margin-top
on it, and comes after the two floated divs; shouldn't the two floated divs appear at the top of the body, and the third div appear 200px down, well below them?
在这里,第三个 div与两个浮动的 div重叠。可是等等; 为什么会这样?当然,浮动元素与块级元素重叠是允许的(根据Floats 规范,“由于浮动不在流中,因此在浮动框之前和之后创建的非定位块框垂直流动,就好像浮动不存在一样."),但是我们的第三个 div 上有margin-top
很多,并且在两个浮动的 div 之后;两个浮动的 div 不应该出现在主体顶部,而第三个 div 向下 200 像素,远低于它们吗?
The reason this doesn't occur is that the margin of the third div collapses into the margin of the divs' parent (in this case, the body - but the same behaviour happens if you wrap all three divs in a parent div). The Collapsing margins spec(quoted below with several irrelevant details omitted) tells us that:
没有发生这种情况的原因是第三个 div 的边距折叠到 div 父级的边距中(在这种情况下,主体 - 但如果将所有三个 div 都包装在一个父 div 中,则会发生相同的行为)。该折叠利润率规范(以下引用省略一些无关的细节)告诉我们:
Adjoining vertical margins collapse...
Two margins are adjoiningif and only if:
- both belong to in-flow block-level boxes that participate in the same block formatting context
- no line boxes, no clearance, no padding and no border separate them ...
- both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
- top margin of a box and top margin of its first in-flow child
- ...
相邻的垂直边距折叠...
两个边距相邻当且仅当:
- 两者都属于参与相同块格式化上下文的流入块级框
- 没有行框,没有间隙,没有填充和没有边框将它们分开......
- 两者都属于垂直相邻的盒子边缘,即形成以下对之一:
- 框的上边距和其第一个流入子项的上边距
- ...
The third div in our example certainly isn't the body's first child, but it is its first in-flowchild. Note that per https://www.w3.org/TR/CSS22/visuren.html#positioning-scheme:
我们示例中的第三个 div 肯定不是 body 的第一个 child,但它是它的第一个in-flowchild。请注意,根据https://www.w3.org/TR/CSS22/visuren.html#positioning-scheme:
An element is called out of flowif it is floated, absolutely positioned, or is the root element. An element is called in-flowif it is not out-of-flow.
如果元素是浮动的、绝对定位的或者是根元素,则该元素被称为流外元素。一个元素被称为在流如果不是乱流。
Since the first and second div in our example are floated, only the third div is in-flow. Thus its top margin adjoins the top margin of its parent, and the margins collapse - pushing down the entire body, includingthe two floated elements. Thus the third div overlaps its siblings despite having a large margin-top
. Consequently - in this hypothetical case, where the third element's clear
is set to none
- we satisfy the condition that:
由于我们示例中的第一个和第二个 div 是浮动的,因此只有第三个 div 是流入的。因此,它的上边距与其父项的上边距相邻,并且边距折叠 - 向下推整个主体,包括两个浮动元素。因此第三个 div 尽管有一个大的margin-top
. 因此 - 在这个假设的情况下,第三个元素clear
被设置为none
- 我们满足以下条件:
the element's top border edge is not past the relevant floats
元素的顶部边框边缘没有超过相关的浮动
Thus:
因此:
clearance is introduced, and margins collapse according to the rules in 8.3.1
引入间隙,边距按8.3.1规则折叠
How much clearance? The spec gives browsers two options, with a couple of clarifying notes:
清关多少?该规范为浏览器提供了两个选项,并附有一些澄清说明:
Then the amount of clearance is set to the greater of:
- The amount necessary to place the border edge of the block even with the bottom outer edge of the lowest float that is to be cleared.
- The amount necessary to place the top border edge of the block at its hypothetical position.
Alternatively, clearance is set exactly to the amount necessary to place the border edge of the block even with the bottom outer edge of the lowest float that is to be cleared.
Note:Both behaviors are allowed pending evaluation of their compatibility with existing Web content. A future CSS specification will require either one or the other.
Note: The clearance can be negative or zero.
然后将间隙量设置为以下两者中的较大者:
- 放置块的边界边缘所需的数量,即使是要清除的最低浮动的底部外边缘。
- 将块的顶部边界边缘放置在其假设位置所需的数量。
或者,间隙被精确设置为放置块的边界边缘所需的量,即使是要清除的最低浮动的底部外边缘。
注意:在评估它们与现有 Web 内容的兼容性之前,允许这两种行为。未来的 CSS 规范将需要其中之一。
注意:间隙可以为负值或零。
Before we can start applying these rules, we immediately hit a complication. Remember that collapsing margin that we had to take into account in the hypotheticalcase where clear
was none
? Well, it doesn'texist in this non-hypotheticalcase where we're calculating the clearance to use, because the existence of the clearance inhibits it. Recall the collapsing margin rules from 8.3.1, quoted earlier, dictate that margins are only adjoiningif:
在我们开始应用这些规则之前,我们立即遇到了一个复杂问题。请记住,塌陷保证金,我们必须考虑到在假定情况下clear
为none
?好吧,在我们计算要使用的许可的这种非假设情况下,它不存在,因为许可的存在抑制了它。回想一下前面引用的8.3.1 中的折叠边距规则,它规定边距仅在以下情况下相邻:
- no line boxes, no clearance, no padding and no border separate them
- 没有行框,没有间隙,没有填充和没有边框将它们分开
(emphasis added). As such, the third div's top margin and the top margin of its parent are no longer adjoining. We can simulate this pre-clearance scenario in our example snippet by keeping clear: none
but adding padding-top: 1px
to the body, which also disables margin collapse, per the rule quoted above.
(强调)。因此,第三个 div 的上边距与其父级的上边距不再相邻。根据上面引用的规则,我们可以通过保留clear: none
但添加padding-top: 1px
到正文来模拟此预清除场景,这也会禁用边距折叠。
body {
padding-top: 1px;
}
<div style="float: left; background: red;">Left</div>
<div style="float: right; background: green;">Right</div>
<div style="clear: none; margin-top: 200px; background: blue;">Main Data</div>
Now, unlike when the margins were collapsed, our third div is comfortably below its two floated siblings. But we have already decided, based upon a hypothetical scenario where the margins didcollapse, that clearance must be added; all that remains is to choose the amountof clearance, in order to:
现在,与边距折叠时不同,我们的第三个 div 舒适地低于它的两个浮动的兄弟。但我们已经决定,根据利润率确实崩溃的假设情况,必须增加间隙;剩下的就是选择清除量,以便:
place the border edge of the block even with the bottom outer edge of the lowest float that is to be cleared
放置块的边界边缘,即使是要清除的最低浮动的底部外边缘
And so we have no choice but to apply a negativeclearance to the third div, in order to drag its top border edgeup to touch the bottom outer edge(also known as margin edge) of the floated elements above it. As such, if the floated elements are each 10px high and the third div has 200px of top margin, -190px of clearance will be applied. That, at last, gets us to the final result seen by the question asker:
因此,我们别无选择,只能对第三个 div应用负间隙,以便向上拖动其顶部边框边缘以接触其上方浮动元素的底部外边缘(也称为边距边缘)。因此,如果每个浮动元素的高度为 10 像素,并且第三个 div 的上边距为 200 像素,则将应用 -190 像素的间隙。最后,让我们得到提问者看到的最终结果:
<div style="float: left; background: red;">Left</div>
<div style="float: right; background: green;">Right</div>
<div style="clear: both; margin-top: 200px; background: blue;">Main Data</div>
(Note that if you inspect the third div in the snippet above using your browser's dev tools, you will still be able to see the 200px of top margin above the div, going way out above all the rest of the content - it's just that the entire margin box has been hauled upwards by the large negative clearance.)
(请注意,如果您使用浏览器的开发工具检查上面代码段中的第三个 div,您仍然可以看到 div 上方 200 像素的顶部边距,超出所有其余内容 - 只是整个边距框已被大的负间隙向上拖拽。)
Simple!
简单的!
回答by rvbyron
Pointy and Randall Cook have excellent answers. I thought I'd show one more solution.
Pointy 和 Randall Cook 给出了很好的答案。我想我会再展示一种解决方案。
<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="float: left; clear: both; margin-top: 200px;">Main Data</div>
If you make the 3rd element "float: left;" AND "clear: both;", it should have the desired effect of giving the 3rd element a 200 pixel margin. Here's a linkto an example.
如果你让第三个元素“浮动:左;” 和“清除:两者;”,它应该具有为第三个元素提供 200 像素边距的预期效果。这是一个示例的链接。
This also might affect other followup elements as to whether they need to be floats or not. However, it might also have the desired effect.
这也可能会影响其他后续元素是否需要浮动。但是,它也可能具有预期的效果。
回答by Simon_Weaver
Alternative solution:
替代解决方案:
You can actually put a
margin-bottom
on the floated elements to push DOWN the element underneath that hasclear: both
.
您实际上可以
margin-bottom
在浮动元素上放置 a以向下推具有clear: both
.
Note: Having made this suggestion I have to immediately retract it as not generally a good idea, but in some limited situations may appropriate;
注意:提出这个建议后,我必须立即撤回它,因为它通常不是一个好主意,但在某些有限的情况下可能是合适的;
<div class='order'>
<div class='address'>
<strong>Your order will be shipped to:</strong><br>
Simon</br>
123 Main St<br>
Anytown, CA, US
</div>
<div class='order-details'>
Item 1<br>
Item 2<br>
Item 3<br>
Item 4<br>
Item 5<br>
Item 6<br>
Item 7<br>
Item 8<br>
Item 9<br>
Item 10<br>
</div>
<div class='options'>
<button>Edit</button>
<button>Save</button>
</div>
</div>
The panel with items is called order-details
with this css
order-details
使用此 css调用带有项目的面板
.order-details
{
padding: .5em;
background: lightsteelblue;
float: left;
margin-left: 1em;
/* this margin does take effect */
margin-bottom: 1em;
}
In the above fiddle - the yellow panel has a margin-top
, but unless it is greater than the tallest floated item then it won't do anything (of course that's the whole point of this question).
在上面的小提琴中 - 黄色面板有一个margin-top
, 但除非它大于最高的浮动项目,否则它不会做任何事情(当然这就是这个问题的重点)。
If you set the margin-top
of the yellow panel to 20em then it will be visible because the margin is calculated from the top of the outer blue box.
如果您将margin-top
黄色面板的 设置为 20em,那么它将可见,因为边距是从外部蓝色框的顶部计算的。
回答by freeworlder
Use 'padding-top' in your main data div instead. Or, alternatively, wrap the main data div in one with 'padding-top'.
改为在主数据 div 中使用“padding-top”。或者,或者,将主数据 div 与“padding-top”合二为一。
回答by christian
Sometimes a combination of position relative and margin can solve these type of problems.
有时,位置相对和保证金的组合可以解决这些类型的问题。
I use this technique for my alignright and alignleft classes in WordPress.
我将此技术用于 WordPress 中的 alignright 和 alignleft 类。
For instance if I want a "bottom margin" that is respected by clearing elements you can use.
例如,如果我想要一个“底部边距”,您可以使用清除元素。
.alignright{
float: right;
margin-left: 20px;
margin-top: 20px;
position: relative;
top: -20px;
}
For your example you could do something like
对于您的示例,您可以执行以下操作
<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="clear: both; margin-bottom: 200px; position: relative; top: 200px;">Main Data</div>
回答by Hyman Cheng
Try setting a bottom margin on one of the floated elements. Alternatively, you can wrap the floats in a parent element, and use a css hack to clear it without additional markup.
尝试在浮动元素之一上设置底部边距。或者,您可以将浮点数包装在父元素中,并使用 css hack清除它,而无需额外的标记。