代码之家  ›  专栏  ›  技术社区  ›  Vishal

边缘顶部不使用clear:both

  •  65
  • Vishal  · 技术社区  · 15 年前

    <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 回复  |  直到 9 年前
        1
  •  66
  •   Community Mohan Dere    9 年前

    你可以把两个漂浮的潜水器放进去 另一个 其中一个设置为“溢出:隐藏”:

    <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 . 一个很好的技巧就是添加一个这样的CSS规则:

    div { border: 1px solid transparent; }
    

    噗!现在(没有我的附加 <div> )它工作得很好!好吧,除了边框上多余的像素。尤其是我 认为 这是一种结合了 clear: both 导致操作中代码意外布局的工作和页边距折叠规则。

    再次编辑 -关于完整(而且,我认为,完全准确)的故事,请参见 Mark Amery's excellent answer . 这个答案掩盖了一些细节的复杂性。

        2
  •  19
  •   Randall Cook    14 年前

    虽然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包装的情况下,这可能会很有用。

        3
  •  12
  •   Mark Amery Harley Holcombe    9 年前

    规范中这一点背后的逻辑是思想扭曲,并且涉及到 clearance的复杂规则交互作用 和 collapping margins 。

    您可能熟悉传统的CSS box model ,其中 content box 包含在a padding box contained with in a border box contained within a margin box :。

    < Buff行情>

    < /块引用>

    对于具有 clear >a>set to something other than none ,可以将附加组件引入到该模型: clearance 。

    < Buff行情>

    “无”以外的值可能会引入 清除。间隙抑制边缘塌陷,并充当元素边缘顶部上方的间距。

    < /块引用>

    换句话说,在这些情况下,盒子模型看起来更像这样:

    但是什么时候开始有间隙,它应该有多大?让我们从第一个问题开始。spec says :

    < Buff行情>

    通过首先确定元素顶部边界边缘的假设位置,计算设置了“clear”的元素的间隙。如果元素的“clear”属性为“none”,则此位置是实际的上边框边缘所在的位置。

    如果元素顶部边界边缘的假设位置没有超过相关浮动,则会引入清除,并且根据8.3.1中的规则,边缘会折叠。

    < /块引用>

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

    <DIV style=“float:right;background:green;”>右</DIV>
    <DIV style=“clear:both;margin-top:200px;background:blue;”>主数据</DIV>>
    

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

    <DIV style=“float:right;background:green;”>右</DIV>
    <DIV style=“clear:none;margin-top:200px;background:blue;”>主数据</DIV>>
    

    这里,第三个div是重叠的。但是等等,为什么会这样?当然,允许浮动元素与块级元素重叠(根据 floats spec , ”因为float is not in the flow,non-positioned block box created before and after the float box flow vertical as if the float did not exist.”,but our third div它上面有 Margin Top 的负载,并且在两个浮动的div之后;这两个浮动的div不应该出现在主体的顶部,而第三个div应该出现200px向下,在它们下面吗?

    之所以没有出现这种情况,是因为第三个div的边距会折叠到divs父级的边距中(在本例中,是主体,但如果将所有三个div都包装在父级div中,则会发生相同的行为)。 collapping margins spec (以下引用,省略了几个不相关的细节)告诉我们:

    < Buff行情>

    相邻的垂直边距折叠…

    两个页边距是相邻的

    • 它们都属于同一块格式上下文中的流块级框。
    • 没有行框,没有净空,没有填充物,没有边框分隔它们…。
    • 它们都属于垂直相邻的盒子边缘,即形成以下一对:
      • 框的上边距及其第一个流入子框的上边距
      • …/LI>
    < /块引用>

    在我们的示例中,第三个部分当然不是body的 first child ,但它是它的first in flow child。请注意,per https://www.w3.org/tr/css22/visuren.html positioning scheme :

    < Buff行情>

    元素被称为“流出”元素,如果它是浮动的、绝对定位的或是根元素。元素在流中被称为 ,if it is not out of flow.

    < /块引用>

    因为我们示例中的第一个和第二个DIV是浮动的,所以只有第三个DIV在流中。因此,它的上边缘与其父元素的上边缘相邻,并且边缘折叠-向下推整个主体, including 两个浮动元素。因此,尽管第三个DIV的 Margin Top 因此-在这种假设情况下,其中第三个元素的 clear 设置为 none -我们满足以下条件:

    < Buff行情>

    元素的上边框边缘未超过相关浮动

    < /块引用> < > > >:< > > < Buff行情>

    根据8.3.1中的规则,引入了间隙和边缘折叠。

    < /块引用>

    间隙有多大?该规范为浏览器提供了两个选项,并提供了一些说明:

    < Buff行情>

    然后将间隙量设置为以下值中的较大值:

    • 放置块边界边缘所需的量,即使是要清除的最低浮动的底部外边缘。
    • 将块的上边界边缘置于其假设位置所需的量。

    或者,间隙精确设置为放置块的边界边缘所需的量,即使是要清除的最低浮动的底部外边缘。

    注: 这两种行为都允许挂起评估其与现有Web内容的兼容性。未来的CSS规范将需要一个或另一个。

    注意:间隙可以为负或零。

    < /块引用>

    < Buff行情>
    • 无接线盒, no clearance ,no padding and no border separate them
    < /块引用>

    (增加了重点)。因此,第三个分区的上边距和其父分区的上边距不再相邻。我们可以在示例片段中通过保持 clear:none but adding padding to p:1px to the body,which also disables margin collapse,per the rule quoted above.

    body{
    垫顶:1px;
    }<代码> < /PRE>
    
    <DIV style=“float:right;background:green;”>右</DIV>
    <DIV style=“clear:none;margin-top:200px;background:blue;”>主数据</DIV>>
    

    现在,与利润率崩溃时不同的是,我们的第三个分区舒服地位于它的两个浮动兄弟分区之下。但是,我们已经决定,基于一个假设的场景,在这个场景中,利润率 did->em>collapse,必须添加该清除;剩下的只是选择清除的 amount->em>,以便:

    < Buff行情>

    放置块的边界边缘,使其与要清除的最低浮动的底部外边缘齐平。

    < /块引用>

    因此,我们别无选择,只能对第三个分区应用一个 负的 间隙,以便拖动其顶部 border edge up以触摸其上方浮动元素的底部 outer edge (也称为 margin edge )。因此,如果浮动元件各为10px高,而第三个分区的上边缘为200px,则应用-190px的间隙。最后,我们得到了提问者看到的最终结果:

    <DIV style=“float:right;background:green;”>右</DIV>
    <DIV style=“clear:both;margin-top:200px;background:blue;”>主数据</DIV>>
    

    (请注意,如果您使用浏览器的dev工具检查上面代码片段中的第三个div,您仍然可以看到该div上方的上边距为200px,远远超过所有其他内容-只是整个边距框被大的负间隙拉向上。)

    简单!

    和 collapsing margins .

    你可能熟悉传统的CSS box model 其中 内容框 包含在 填充盒 包含在 边框 包含在 边缘盒 :

    Diagram of box model

    对于具有 clear 设置为除 none ,可以向该模型引入一个附加组件: 间隙 .

    “无”以外的值可能会引入 间隙 . 间隙抑制边缘塌陷,并充当元素边缘顶部上方的间距。

    换句话说,在这些情况下,盒子模型看起来更像这样:

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

    但是什么时候开始有间隙,它应该有多大?让我们从第一个问题开始。规格 says :

    通过首先确定元素顶部边界边缘的假设位置,计算设置了“clear”的元素的间隙。如果元素的“clear”属性为“none”,则此位置是实际的上边框边缘所在的位置。

    如果元素顶部边界边缘的假设位置不超过相关浮动,则会引入清除,并且根据8.3.1中的规则,边缘会折叠。

    让我们把这个逻辑应用到提问者的代码中。请记住,我们正在试图解释下面代码中第三个分区的位置(添加背景以帮助可视化):

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

    让我们想象一下,正如规范要求的那样, 清楚的 设置为 没有人 在第三个分区,而不是 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>

    这里,第三个分区是 重叠 两个漂浮的潜水器。但是等等,为什么会这样?当然,允许浮动元素重叠块级元素(根据 Floats spec , 由于浮动不在流中,因此浮动框前后创建的非定位块框垂直流动,就好像浮动不存在一样。 但是我们的第三个师有很多 margin-top 在它上面,在两个浮动的分隔符之后;这两个浮动的分隔符是不是应该出现在身体的顶部,而第三个分隔符是不是应该向下200px,就在它们下面?

    之所以没有出现这种情况,是因为第三个div的边距会折叠到divs父级的边距中(在本例中,是主体,但如果将所有三个div都包装在父级div中,则会发生相同的行为)。这个 Collapsing margins spec (以下引用,省略了几个不相关的细节)告诉我们:

    相邻的垂直边距折叠…

    两个边距是 毗邻的 当且仅当:

    • 它们都属于同一块格式上下文中的流块级框。
    • 没有行框,没有空白,没有填充,没有边框分隔它们…
    • 它们都属于垂直相邻的盒子边缘,即形成以下一对:
      • 框的上边距及其第一个流入子框的上边距
      • …

    我们例子中的第三个部分肯定不是身体的 第一个孩子 但这是第一次 在流动中 孩子。请注意 https://www.w3.org/TR/CSS22/visuren.html#positioning-scheme :

    元素被调用 流出的 如果它是浮动的、绝对定位的或是根元素。元素被调用 在流动中 如果没有断流。

    因为我们示例中的第一个和第二个DIV是浮动的,所以只有第三个DIV在流中。因此,它的上边缘与其父级的上边缘相邻,并且边缘折叠-向下推整个主体, 包括 两个浮动元素。因此,尽管第三个分区的 缘顶 . 因此-在这种假设情况下,第三个元素 清楚的 设置为 没有人 -我们满足以下条件:

    元素的上边框边缘未超过相关浮动

    因此:

    根据8.3.1中的规则,引入了间隙和边缘折叠。

    间隙有多大?该规范为浏览器提供了两个选项,并提供了一些澄清说明:

    然后将间隙量设置为以下值中的较大值:

    • 将块的边框边缘与要清除的最低浮动的底部外边缘齐平所需的量。
    • 将块的上边界边缘置于其假设位置所需的量。

    或者,间隙精确设置为放置块的边界边缘所需的量,即使是要清除的最低浮动的底部外边缘。

    注: 这两种行为在与现有Web内容的兼容性评估之前都是允许的。未来的CSS规范将需要一个或另一个。

    注意:间隙可以为负或零。

    在我们开始应用这些规则之前,我们马上遇到了一个复杂的问题。记住,我们必须在 假设 情况在哪里 清楚的 是 没有人 ?嗯,它 不 存在于此 非假设 在这种情况下,我们计算要使用的间隙,因为间隙的存在会抑制它。回忆起 collapsing margin rules from 8.3.1 ,在前面引用,指示页边距仅为 毗邻的 如果:

    • 无线盒, 无间隙 ,没有填充和边框分隔它们

    (增加了重点)。因此,第三个分区的上边距和其父分区的上边距不再相邻。我们可以通过保持 clear: none 但加入 padding-top: 1px 根据上面引用的规则,也可以禁用页边距折叠。

    body {
      padding-top: 1px;
    }
    <DIV style=“float:left;background:red;”>左</DIV>
    <DIV style=“float:right;background:green;”>右</DIV>
    <DIV style=“clear:none;margin-top:200px;background:blue;”>主数据</DIV>

    现在,与利润率崩溃时不同的是,我们的第三个分区舒服地位于它的两个浮动兄弟分区之下。但是我们已经根据假设的情况决定了 做 折叠,必须增加间隙;剩下的就是选择 数量 为了:

    放置块的边界边缘,使其与要清除的最低浮动的底部外边缘齐平。

    所以我们别无选择只能申请 消极的 与第三个分区的间隙,以便拖动其顶部 边界边缘 向上触摸底部 外缘 (也称为 边缘边缘 )上面漂浮的元素。因此,如果浮动元件各为10px高,而第三个分区的上边缘为200px,则应用-190px的间隙。最后,我们得到了提问者看到的最终结果:

    <DIV style=“float:left;background:red;”>左</DIV>
    <DIV style=“float:right;background:green;”>右</DIV>
    <DIV style=“clear:both;margin-top:200px;background:blue;”>主数据</DIV>

    (请注意,如果您使用浏览器的dev工具检查上面代码片段中的第三个div,您仍然可以看到该div上方的上边距为200px,远远超过所有其他内容-这只是因为整个边距框被大的负间隙拉向上。)

    简单!

    在我们开始应用这些规则之前,我们马上遇到了一个复杂的问题。还记得我们在假设的情况下必须考虑的收拢保证金吗? case where clear was none ?嗯,它不存在于这个非假设的情况下,我们正在计算要使用的间隙,因为间隙的存在抑制了它。回想一下 8.3.1中的following margin rules,quoted earlier,dicte that margins are only adjoined

        4
  •  7
  •   rvbyron    12 年前

    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;”和“clear:both;”,则它应该具有为第三个元素提供200像素边距的预期效果。这里有一个 link 举个例子。

    这也可能影响其他后续元素,决定它们是否需要浮动。然而,它也可能具有预期的效果。

        5
  •  4
  •   Simon_Weaver    12 年前

    备选方案:

    < Buff行情>

    实际上,您可以在浮动元素上放置一个 Margin Bottom 向下移动下面具有 clear:both 的元素。

    < /块引用>

    http://jsfiddle.net/9ey4r/

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


    <div class='order'>
    
    <DIV class='address'>
    <STRONG>您的订单将发送至:</STRONG><br>
    西蒙</br>
    123主街道<br>
    加州美国安镇
    &L/DIV & GT;
    
    <DIV class='order-details'>
    项目1<br>
    项目2<br>
    项目3<br>
    项目4<br>
    项目5<br>
    第6项<br>
    项目7<br>
    第8项<br>
    项目9<br>
    项目10<br>
    &L/DIV & GT;
    
    <DIV class='options'>
    <button>编辑</button>
    <button>保存</button>
    &L/DIV & GT;
    &L/DIV & GT;
    < /代码> 
    
    

    带有项目的面板称为order detailswith this css

    。订单详情
    {
    填充物:5EM;
    背景:浅钢蓝;
    
    浮动:左;
    左边距:1米;
    
    /*这个差额确实生效*/
    底部边缘:1米;
    }
    < /代码> 
    
    

    在上面的小提琴中-黄色面板有一个Margin Top,但是除非它大于最高的浮动项,否则它不会做任何事情(当然,这就是这个问题的全部要点)。

    如果将黄色面板的Margin Top设置为20em,则它将可见,因为从外部蓝色框的顶部计算出了边缘。

    在漂浮的元素上推动 下面的元素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>
    

    带有项的面板称为order-details用这个CSS

    .order-details
    {
        padding: .5em;
        background: lightsteelblue;
    
        float: left;
        margin-left: 1em;
    
        /* this margin does take effect */
        margin-bottom: 1em;
    }
    

    在上面的小提琴-黄色面板有一个margin-top但是,除非它大于最高的浮动项,否则它不会做任何事情(当然,这就是这个问题的关键所在)。

    如果你设置缘顶从黄色面板到20em,那么它将可见,因为边缘是从外部蓝色框的顶部计算出来的。

        6
  •  2
  •   Colin R. Turner    14 年前

    在主数据分区中使用“padding top”。或者,也可以用“padding top”将主数据分区包装在一起。

        7
  •  0
  •   Jack Cheng    15 年前

    尝试在其中一个浮动元素上设置下边距。或者,可以将浮动包装在父元素中,并使用css hack clear it without additional markup .

        8
  •  0
  •   christian    12 年前

    有时,位置相对和边缘的组合可以解决这类问题。

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