<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="clear: both; margin-top: 200px;">Main Data</div>
为什么margin:top
“主数据”在上面的代码中不起作用?
<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="clear: both; margin-top: 200px;">Main Data</div>
为什么margin:top
“主数据”在上面的代码中不起作用?
Answers:
您可以将两个浮动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>
编辑—为这个已有5年历史的答案添加一点点:我认为造成混乱行为的原因是利润率下降的过程有些复杂。OP中原始HTML的一个好技巧是添加一个CSS规则,如下所示:
div { border: 1px solid transparent; }
of!现在(没有我的附加要求<div>
)可以正常工作!好吧,除了边界上的多余像素。特别是,我认为这是clear: both
工作方式与边距折叠规则的结合,这些规则会导致OP中的代码出现意外的布局。
再次编辑-有关完整(并且我认为完全准确)的故事,请参阅Mark Amery的出色答案。细节有一些复杂性,这个答案可以掩盖。
虽然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>
在不希望在某些HTML周围添加div包装器的情况下,这可能会很有用。
规范中此背后的逻辑是弯腰的,并且涉及清除规则和利润率下降的规则之间的复杂相互作用。
你可能熟悉的常规CSS盒模型,其中内容框包含一个内填充盒包含一个内边界框包含一个内缘盒:
对于clear
设置为以外的元素,none
此模型可能会引入一个附加组件:间隙。
除“ none”以外的其他值可能会导致清除。间隙可防止边距折叠,并充当元素边距顶部上方的间距。
换句话说,在这种情况下,盒子模型看起来更像这样:
但是,什么时候引入间隙,它应该有多大?让我们从第一个问题开始。规范说:
通过首先确定元素顶部边界的假定位置,可以计算出设置了“清除”的元素的间隙。如果元素的“ clear”属性为“ none”,则实际的顶部边界将位于该位置。
如果元素的顶部边框边缘的此假设位置未超过相关的浮动,则将引入间隙,并且边缘会根据8.3.1中的规则收缩。
让我们将此逻辑应用于提问者代码。记住,我们试图在下面的代码中解释第三个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>
让我们想象一下,按照规范要求,将clear
其设置为none
第三分区,而不是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>
在这里,第三个div与两个浮动div重叠。可是等等; 为什么会这样呢?当然,允许浮动元素与块级元素重叠(根据Floats规范,“由于浮动中没有浮动,因此在浮动框之前和之后创建的未定位区块框会垂直流动,就好像该浮动不存在一样) ”,但是我们的第三个div上有很多负载,margin-top
紧随两个浮动div之后;两个浮动div不应出现在主体顶部,而第三个div则应位于其下方200px下方吗?
不会发生这种情况的原因是,第三个div的边距塌陷到divs父级的边距中(在本例中为body,但是如果将所有三个div包装在父div中,则会发生相同的行为)。该折叠利润率规范(以下引用省略一些无关的细节)告诉我们:
相邻的垂直边距崩溃...
当且仅当以下情况时,两个边距相邻:
- 都属于流内块级框,它们参与相同的块格式上下文
- 没有线框,没有间隙,没有填充和没有边框将它们分开...
- 都属于垂直相邻的框边,即形成以下对之一:
- 盒子的上边距和第一个流入子元素的上边距
- ...
在我们的示例中,第三个div当然不是人体的第一个子对象,而是它的第一个流入子对象。请注意,根据https://www.w3.org/TR/CSS22/visuren.html#positioning-scheme:
如果某个元素是浮动的,绝对定位的或者是根元素,则该元素被称为流出。一个元素被称为在流如果不是乱流。
由于我们示例中的第一个和第二个div是浮动的,因此只有第三个div是流入的。因此,其上边距与其父对象的上边沿相邻,并且边沿崩溃-压低整个身体,包括两个浮动元素。因此,尽管有较大的div,但第三个div却与兄弟姐妹重叠margin-top
。因此,在这种假设的情况下,第三个元素clear
设置为none
,我们满足以下条件:
元素的顶部边框边缘不超过相关的浮动
从而:
引入了清除功能,边距按照8.3.1中的规则崩溃
有多少通关?该规范为浏览器提供了两种选择,并提供了一些澄清说明:
然后将间隙量设置为以下较大者:
- 即使要清除的最低浮标的底部外边缘,也要放置块的边界边缘所需的数量。
- 将块的顶部边界放置在其假定位置所需的数量。
或者,将间隙精确设置为放置块的边界边缘所需的量,即使要清除的最低浮标的底部外边缘也是如此。
注意:在评估它们与现有Web内容的兼容性之前,都允许这两种行为。将来的CSS规范将需要一个或另一个。
注意:间隙可以为负或零。
在开始应用这些规则之前,我们立即遇到了麻烦。请记住,塌陷保证金,我们必须考虑到在假定情况下clear
为none
?好吧,在我们要计算要使用的游隙的这种非假设情况下,它并不存在,因为游隙的存在会抑制它。回想一下前面引用的8.3.1中的崩溃边距规则,该边距规则仅在以下情况下才邻接:
- 没有线框,没有间隙,没有填充和没有边框将它们分开
(添加了重点)。因此,第三个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>
现在,与利润率崩溃时不同,我们的第三个div舒适地低于其两个浮动兄弟姐妹。但是我们已经基于一种假设情况,即利润确实倒塌了,必须决定增加净空;剩下的就是选择许可数量,以便:
将块的边界边缘与要清除的最低浮点的底部外边缘平齐
因此,我们别无选择,只能对第三个div施加负间隙,以向上拖动其顶部边界以接触其上方浮动元素的底部外边缘(也称为边界边缘)。因此,如果浮动元素的高度分别为10px,并且第三个div的上边距为200px,则将应用-190px的间隙。最后,这使我们获得了质询者看到的最终结果:
<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>
(请注意,如果您使用浏览器的开发工具检查以上代码段中的第三个div,则仍然可以看到div上方的200px的上边距,超出了所有其他内容的范围-仅仅是较大的负间隙将整个边距框向上拉起。)
简单!
overflow: auto
还是overflow: hidden
在父容器上,@ Pointy可以解决问题例如stackoverflow.com/a/6204990/1709587(尽管由于某些原因,如果容器是元素,则无法使用)。我不太确定为什么这样做,因为它取决于“块格式化上下文”的定义(我尚未研究并且目前尚不了解)。body
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>
如果将第三个元素设为“ float:left;” AND“ clear:both;”,它应该具有给第3个元素200像素边距的预期效果。这是一个示例的链接。
这也可能影响其他后续元素是否需要浮动。但是,它也可能具有预期的效果。
替代解决方案:
实际上,您可以
margin-bottom
在浮动元素上放一个,以将向下推到具有的元素下方clear: both
。
注意:提出建议后,我通常必须立即撤消该建议,但在某些有限的情况下可能是合适的;
<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>
带有项目的面板order-details
与此CSS一起调用
.order-details
{
padding: .5em;
background: lightsteelblue;
float: left;
margin-left: 1em;
/* this margin does take effect */
margin-bottom: 1em;
}
在上面的小提琴中-黄色面板有一个margin-top
,但是除非它大于最高的浮动项目,否则它什么也不会做(当然,这就是问题的全部内容)。
如果margin-top
将黄色面板的设置为20em,则将可见,因为边距是从外部蓝色框的顶部计算的。
尝试在其中一个浮动元素上设置底边距。或者,您可以将浮点数包装在父元素中,并使用css hack清除它,而无需其他标记。
有时,相对头寸和保证金的组合可以解决这类问题。
我将这种技术用于WordPress中的alignright和alignleft类。
例如,如果我想要一个“底边距”,您可以使用清除元素来尊重它。
.alignright{
float: right;
margin-left: 20px;
margin-top: 20px;
position: relative;
top: -20px;
}
例如,您可以执行类似
<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>