<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="clear: both; margin-top: 200px;">Main Data</div>
为什么“主要数据”的margin:top
在上面的代码中不起作用?
答案 0 :(得分:66)
您可以将两个浮动的div放入另一个另一个,其中包含“overflow:hidden”设置:
<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年历史的答案添加一点:我认为混淆行为的原因是margin collapse有点复杂的过程。使用OP中的原始HTML的一个好方法是添加如下的CSS规则:
div { border: 1px solid transparent; }
噗!现在(没有我的额外<div>
)它工作正常!好吧,除了来自边界的额外像素。特别是,我认为它是clear: both
工作方式和边缘折叠规则的组合,导致OP中代码的意外布局。
再次编辑 - 有关完整(并且我认为完全准确)的故事,请参阅Mark Amery's excellent answer。细节有一些复杂性,这个答案掩盖了。
答案 1 :(得分:19)
虽然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包装器,这可能会很有用。
答案 2 :(得分:12)
规范背后的逻辑是令人费解的,涉及clearance和collapsing margins规则的复杂互动。
您可能熟悉传统的CSS box model,其中内容框包含在包含在填充框中边距框中包含的>边框:
对于clear
设置为none
以外的元素的元素,可以在此模型中引入其他组件: clearance 。
&#39; none&#39;以外的值可能会引入清除。间隙抑制了边缘坍塌,并且作为元素边缘上方的间距。
换句话说,那些案例中的盒子模型看起来更像是这样:
但什么时候介绍清关,它应该有多大?让我们从第一个问题开始吧。规范says:
计算清除&#39;清除的元素的清除率。通过首先确定元素的顶部边界边缘的假设位置来完成设置。如果元素清除,则该位置是实际顶部边界边缘的位置。财产一直没有&#39;
。如果元素顶部边界边缘的假设位置未超过相关浮点数,则引入间隙,边距根据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>
&#13;
让我们想象,正如规范要求的那样,clear
在第三个div上设置为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>
&#13;
这里,第三个div是重叠两个浮动的div。可是等等;为什么会这样?当然,浮动元素可以重叠块级别(根据Floats spec,&#34;由于浮动不在流中,因此在之前创建的非定位块框和在浮动框垂直流动之后,就像浮动不存在一样。&#34; ),但我们的第三个div上有margin-top
个加载,并且在两个浮动的div之后;不应该是两个浮动的div出现在身体的顶部,第三个div显示200px下降,远低于它们?
这没有发生的原因是第三个div的边缘崩溃到了div的边缘。 parent(在这种情况下,正文 - 但如果在父div中包含所有三个div,则会发生相同的行为)。 Collapsing margins spec(下面引用了几个不相关的详细信息)告诉我们:
相邻的垂直边距崩溃......
两个边距 毗邻 当且仅当:
- 都属于参与相同块格式化上下文的流内块级框
- 没有行框,没有间隙,没有填充,没有边框将它们分开......
- 都属于垂直相邻的盒子边缘,即形成以下对中的一个:
- 盒子的上边距及其第一个流入的孩子的上边距
- ...
我们示例中的第三个div当然不是身体第一个孩子,但它是第一个 in-flow 孩子。请注意,按https://www.w3.org/TR/CSS22/visuren.html#positioning-scheme:
如果元素浮动,绝对定位或是根元素,则该元素称为 流出 。如果元素不在流量范围内,则称为 in-flow 。
由于我们示例中的第一个和第二个div是浮动的,因此只有第三个div是in-flow。因此,它的上边距与其父母的上边缘相邻,边缘坍塌 - 向下推动整个身体,包括两个浮动元素。因此,尽管有一个很大的margin-top
,第三个div与其兄弟姐妹重叠。因此 - 在这个假设的情况下,第三个元素clear
被设置为none
- 我们满足以下条件:
元素的顶部边框边缘未超过相关的浮点数
因此:
引入了清除,并且边距根据8.3.1 中的规则崩溃
多少许可?该规范为浏览器提供了两个选项,其中包括几个澄清说明:
然后将间隙量设置为以下值:
- 即使在要清除的最低浮动的底部外边缘处放置块的边缘所需的数量。
- 将块的顶部边缘放置在其假设位置所需的量。
或者,将间隙精确设置为放置块的边缘所需的量,即使要清除最下面的浮动的底部外边缘也是如此。
注意: 允许这两种行为等待评估其与现有Web内容的兼容性。未来的CSS规范将需要一个或另一个。
注意:间隙可以是负数或零。
在我们开始应用这些规则之前,我们立即遇到了并发症。请记住,在clear
为none
的假设案例中,我们必须考虑折扣保证金?好吧, 回想一下之前引用的collapsing margin rules from 8.3.1,如果符合以下情况,则指示边距仅为 毗邻 :
- 没有行框, 没有间隙 ,没有填充,没有边框将它们分开
(重点补充)。因此,第三个div的上边距和其父母的上边距不再相邻。我们可以在示例代码段中模拟此预先清除方案,方法是保留clear: none
,同时根据上面引用的规则将padding-top: 1px
添加到正文,这也会禁用边距折叠。
body {
padding-top: 1px;
}
&#13;
<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>
&#13;
现在,与边缘坍塌不同的是,我们的第三个分区比其两个漂浮的兄弟姐妹还要舒服。但是我们已经决定,基于假设的情况,确实崩溃,必须增加许可;剩下的就是选择金额的许可,以便:
放置块的边缘,即使是要清除的最低浮点的底部外边缘
因此我们别无选择,只能将否定清除应用于第三个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>
&#13;
(请注意,如果您使用浏览器的开发工具检查上面代码段中的第三个div,您仍然可以看到div上方200px的上边距,远远高于其余部分内容 - 只是整个保证金框已被大量负面许可向上拖走。)
简单!
答案 3 :(得分:7)
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>
如果你使第3个元素“float:left;” AND“clear:both;”,它应该具有给第三个元素提供200像素边距的预期效果。这是一个link的示例。
这也可能会影响其他后续元素是否需要浮动。但是,它也可能产生预期的效果。
答案 4 :(得分:4)
替代解决方案:
您实际上可以在要浮动的元素上放置
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>
带有项目的面板使用此css称为order-details
.order-details
{
padding: .5em;
background: lightsteelblue;
float: left;
margin-left: 1em;
/* this margin does take effect */
margin-bottom: 1em;
}
在上面的小提琴中 - 黄色面板有margin-top
,但除非它大于最高浮动项目,否则它不会做任何事情(当然这是这个问题的重点)。
如果您将黄色面板的margin-top
设置为20em,那么它将可见,因为边距是从外部蓝色框的顶部计算的。
答案 5 :(得分:2)
在主数据div中使用'padding-top'。或者,也可以使用“padding-top”将主数据div包装在一起。
答案 6 :(得分:0)
尝试在其中一个浮动元素上设置下边距。或者,您可以将浮动包装在父元素中,并使用css hack clear it without additional markup。
答案 7 :(得分:0)
有时位置相对和边距的组合可以解决这些类型的问题。
我将这种技术用于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>