div中的浮动元素,在div之外浮动。为什么?


274

假设您有一个div,给它一个定值width,然后在其中添加元素,在我的情况下为img另一个div

这个想法是容器的内容div将导致容器div伸展,并成为内容的背景。但是,当我这样做时,容纳物会div收缩以适合非漂浮的物体,并且漂浮的物体将一直伸出,或者一半伸出,一半进入,并且对big的大小没有任何影响div

为什么是这样?有什么我想念的东西,怎么才能让漂浮的物品伸出height其中的东西div呢?

Answers:


397

最简单的方法是放在overflow:hidden父div上,而不指定高度:

#parent { overflow: hidden }

另一种方法是也浮动父div:

#parent { float: left; width: 100% }

另一种方法使用明确的元素:

<div class="parent">
   <img class="floated_child" src="..." />
   <span class="clear"></span>
</div>

的CSS

span.clear { clear: left; display: block; }

17
它可以工作,但是现在我困惑了两倍:是否对此有一个解释,或者这到底是怎么回事?
DavidR 2010年

7
是的,有一个解释,但因为我已经忘记了:(它只是它是如何的。overflow:hidden部队的浏览器,它可以将最好包含父的子元素,这就是为什么它修复它。
道格Neiner

5
我认为overflow: hidden这里的解释是:link。并非常感谢,它为我工作
维卡斯阿罗拉

6
@DavidR最简单的解释是html / css是一种过时的,思想欠佳且实施不良的技术。实际上,这种推理实际上解释了自您撰写本文以来毫无疑问遇到的许多html / css怪癖。
2015年

1
请记住,overflow: hidden这只会隐藏从父容器流出的元素的任何部分。对我来说,这导致文本的某些位变得不可读。
顶级猫

160

原因

问题是浮动元素流出了

如果一个元素是浮动的,绝对定位的或者是根元素,则该元素被称为流出

因此,它们不会像流入元素那样影响周围的元素。

这在9.5 Floats中有解释:

由于浮动中没有浮动,因此在浮动框之前和之后创建的未定位块框将垂直流动,就好像浮动不存在一样。但是,根据需要缩短在浮点数旁边创建的当前和后续行框,以便为浮点数的边距框腾出空间。

在此处输入图片说明

这在10.6计算高度和边距中也有规定。对于“正常”区块

仅考虑正常流程中的子级(即,忽略浮动框和绝对定位的框[…])

在此处输入图片说明

hacky解决方案:清除

解决该问题的一种方法是将一些流入元素强制置于所有浮子下方。然后,父级的高度将增加以包装该元素(因此,浮点数也将增加)。

这可以通过使用来实现clear属性

此属性指示元素框的哪些边可能 与较早的浮动框相邻。

在此处输入图片说明

所以一个解决方案是添加一个空元素clear: both作为浮点数的最后一个兄弟

<div style="clear: both"></div>

但是,这不是语义。因此最好在父级末尾生成一个伪元素

.clearfix::after {
  clear: both;
  display: block;
}

此方法有多种变体,例如,使用不赞成使用的单冒号语法:after来支持旧的浏览器,或使用其他块级显示,例如display: table

解决方案:BFC根

开头定义的问题行为有一个例外:如果一个块元素建立了一个块格式化上下文(是BFC根),那么它还将包装其浮动内容。

根据第10.6.7节“自动”高度来设置上下文根的块格式

如果元素具有任何浮动后代,其后边缘的边缘低于元素的底部内容边缘,则高度会增加以包括这些边缘。

在此处输入图片说明

此外,如9.5 Floats所述,由于以下原因,BFC根也很有用:

表的边框,块级替换的元素或正常流程中建立新块格式上下文的元素[…]不得与该元素本身在同一块格式上下文中的任何浮点数的空白框重叠。

在此处输入图片说明

通过以下方式建立块格式化上下文

  • overflow除以外的方块盒visible,例如hidden

    .bfc-root {
      overflow: hidden;
      /* display: block; */
    }
  • 块容器未阻止盒:当display设置为inline-blocktable-celltable-caption

    .bfc-root {
      display: inline-block;
    }
  • 浮动元素:何时float设置为leftright

    .bfc-root {
      float: left;
    }
  • 绝对定位的元素:when position设置为absolutefixed

    .bfc-root {
      position: absolute;
    }

请注意,这些可能具有不希望的附带影响,例如剪切溢出的内容,使用“ 缩小以适合”算法计算自动宽度或变得流出。因此,问题在于不可能有一个具有可见溢出的流内块级元素来建立BFC。

显示器L3解决了这些问题:

创建了flow内部显示类型,以更好地表达流程布局显示类型,并创建用于使元素成为BFC根的显式开关。(这样应该可以消除像黑客需要和[...])flow-root ::after { clear: both; }overflow: hidden

可悲的是,尚无浏览器支持。最终我们也许可以使用

.bfc-root {
  display: flow-root;
}

1
因此,浮动框不会被其父容器识别,因此高度会崩溃,但会被其兄弟姐妹识别,从而导致clearfix?
symlink

@symlink是的,父容器不会增长以包围浮点数,除非它们是BFC根。不是BFC根的同级不会直接受块影响(但其行框会受到影响)。但是,间隙会将它们移动到任何先前的浮动位置之下。
Oriol

“不是BFC根的兄弟姐妹不会直接受到块的影响(但它们的行框会受到影响)。” -您能澄清一下吗?您的意思是在此jsFiddle:jsfiddle.net/aggL3Lk7/2中,浮动的内嵌图像不影响跨度(因此跨度的边框将其重叠),但是该图像影响文本(即行框),如图所示文字没有与图像重叠?
symlink

1
@symlink是的,完全正确。好吧,在您的小提琴中,边界属于父级,但对兄弟姐妹而言基本上是相同的:jsfiddle.net/aggL3Lk7/3
Oriol

1
我同意。这应该是公认的答案。对我而言,有趣的是W3正在调用我们被迫编写“ hack”的方式。有人搞砸了。
DR01D



11

没有什么丢失。Float是为希望将图像(例如)放置在文本的几段旁边而设计的,以便文本在图像周围流动。如果文本“拉伸”了容器,那将不会发生。您的第一个段落将结束,然后您的下一个段落将在图像下方开始(可能在下面几百个像素处)。

这就是为什么您得到自己的结果。


3
与浮动元素正确拉伸父级的高度有什么关系?
2015年

11

在某些情况下,即当(如果)您只是要使float元素在同一“行”上流动时,可以使用

display: inline-block;

代替

float: left;

否则,最后使用clear元素会起作用,即使需要元素来完成CSS工作也可能会遇到麻烦。


11

这是更现代的方法:

.parent {display: flow-root;} 

没有更多的clearfix。

ps使用溢出:隐藏;隐藏盒子阴影,以便...


也可以在Safari 11中使用
即将

7

谢谢LSerni,您为我解决了这个问题。

为达到这个 :

+-----------------------------------------+
| +-------+                     +-------+ |
| | Text1 |                     | Text1 | |
| +-------+                     +-------+ |
|+----------------------------------------+

您必须这样做:

<div style="overflow:auto">
    <div style="display:inline-block;float:left"> Text1 </div>
    <div style="display:inline-block;float:right"> Text2 </div>
</div>

4

正如卢卡斯所说,您所描述的是float属性的预期行为。令许多人感到困惑的是,为了弥补CSS布局模型中的缺陷,float已被远远超出了其最初的预期用途。

如果您想更好地了解此属性的工作原理,请查看Floatutorial


0

首先,您可以轻松地进行操作,可以使div flex并向左或向右应用证明内容,并且可以解决问题。

<div style="display: flex;padding-bottom: 8px;justify-content: flex-end;">
					<button style="font-weight: bold;outline: none;background-color: #2764ff;border-radius: 3px;margin-left: 12px;border: none;padding: 3px 6px;color: white;text-align: center;font-family: 'Open Sans', sans-serif;text-decoration: none;margin-right: 14px;">Sense</button>
				</div>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.