margin-top无法使用clear:both

时间:2010-11-16 19:46:34

标签: css css-float

<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="clear: both; margin-top: 200px;">Main Data</div>

为什么“主要数据”的margin:top在上面的代码中不起作用?

8 个答案:

答案 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)

规范背后的逻辑是令人费解的,涉及clearancecollapsing margins规则的复杂互动。

您可能熟悉传统的CSS box model,其中内容框包含在包含在填充框边距框中包含的>边框

  

Diagram of box model

对于clear设置为none以外的元素的元素,可以在此模型中引入其他组件: clearance

  

&#39; none&#39;以外的值可能会引入清除。间隙抑制了边缘坍塌,并且作为元素边缘上方的间距。

换句话说,那些案例中的盒子模型看起来更像是这样:

Box model with 'clearance' added above the top of the margin box

但什么时候介绍清关,它应该有多大?让我们从第一个问题开始吧。规范says

  

计算清除&#39;清除的元素的清除率。通过首先确定元素的顶部边界边缘的假设位置来完成设置。如果元素清除,则该位置是实际顶部边界边缘的位置。财产一直没有&#39;

     

如果元素顶部边界边缘的假设位置未超过相关浮点数,则引入间隙,边距根据8.3.1中的规则崩溃。

让我们将这个逻辑应用于提问者的代码。请记住,我们正试图在下面的代码中解释第三个div的位置(为了可视化而添加的背景):

&#13;
&#13;
<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;
&#13;
&#13;

让我们想象,正如规范要求的那样,clear在第三个div上设置为none,而不是both。那么上面的代码片段会是什么样的?

&#13;
&#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;
&#13;
&#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规范将需要一个或另一个。

     

注意:间隙可以是负数或零。

在我们开始应用这些规则之前,我们立即遇到了并发症。请记住,在clearnone假设案例中,我们必须考虑折扣保证金?好吧, 回想一下之前引用的collapsing margin rules from 8.3.1,如果符合以下情况,则指示边距仅为 毗邻

  
      
  • 没有行框, 没有间隙 ,没有填充,没有边框将它们分开
  •   

(重点补充)。因此,第三个div的上边距和其父母的上边距不再相邻。我们可以在示例代码段中模拟此预先清除方案,方法是保留clear: none,同时根据上面引用的规则将padding-top: 1px添加到正文,这也会禁用边距折叠。

&#13;
&#13;
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;
&#13;
&#13;

现在,与边缘坍塌不同的是,我们的第三个分区比其两个漂浮的兄弟姐妹还要舒服。但是我们已经决定,基于假设的情况,确实崩溃,必须增加许可;剩下的就是选择金额的许可,以便:

  

放置块的边缘,即使是要清除的最低浮点的底部外边缘

因此我们别无选择,只能将否定清除应用于第三个div,以便将其顶部边框边缘向上拖动以触及底部上边浮动元素的外边(也称为边缘边)。因此,如果浮动元素每个高10px而第三个div具有200px的上边距,则将应用-190px的间隙。最后,这让我们得到了提问者看到的最终结果:

&#13;
&#13;
<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;
&#13;
&#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的元素。

http://jsfiddle.net/9EY4R/

enter image description here

注意:提出这个建议之后我必须立即撤回它,因为这通常不是一个好主意,但在某些有限的情况下可能是合适的;


<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>