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

Dav*_*idR 258 html css css-float

假设你有一个div,说你把它涂成绿色并给它一个明确的宽度,当我把东西放进去时,在我的情况下是一个img和另一个div.这个想法是容器div的内容将导致容器div伸展出来,并成为内容的背景.但是当我这样做时,包含的div缩小以适应非浮动对象,并且浮动对象将要么一直出来,要么是一半,一半,并且与大div的大小没有任何关系.

为什么是这样?有没有我缺少的东西,我怎样才能获得浮动的物品来拉伸包含div的高度?

Dou*_*ner 382

最简单的是放置overflow:hidden父div并且不指定高度:

#parent { overflow: hidden }
Run Code Online (Sandbox Code Playgroud)

另一种方法是浮动父div:

#parent { float: left; width: 100% }
Run Code Online (Sandbox Code Playgroud)

另一种方式使用清晰元素:

<div class="parent">
   <img class="floated_child" src="..." />
   <span class="clear"></span>
</div>
Run Code Online (Sandbox Code Playgroud)

CSS

span.clear { clear: left; display: block; }
Run Code Online (Sandbox Code Playgroud)

  • 它有效,但现在我有两倍的困惑:是否有这样的解释或者这是怎么回事? (14认同)
  • 是的,有一个解释,但我已经忘记了它:(它就是它的原因.`overflow:hidden`强制浏览器尽可能地包含父元素的子元素.这就是为什么它修复它. (7认同)
  • @DavidR最简单的解释是html/css是一个过时的,经过深思熟虑的,并且实现得很差的技术.事实上,这个推理实际上解释了自从你发表这篇文章以来你无疑遇到的很多html/css怪癖. (6认同)
  • 我认为`overflow:hidden`的解释在这里:[link](http://colinaarts.com/articles/the-magic-of-overflow-hidden/).非常感谢,它对我有用 (5认同)
  • 请记住,`overflow: hidden` 只会隐藏流出父容器的元素的任何部分。对我来说,这导致某些文本变得不可读。 (2认同)

Ori*_*iol 150

原因

问题是浮动元素是不流动的:

如果元素浮动,绝对定位或是根元素,则称其为流出流.

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

这在9.5 Floats中解释:

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

在此输入图像描述

html {
  width: 550px;
  border: 1px solid;
}
body {
  font-family: sans-serif;
  color: rgba(0,0,0,.15);
}
body:after {
  content: '';
  display: block;
  clear: both;
}
div {
  position: relative;
}
div:after {
  font-size: 200%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}
.block-sibling {
  border: 3px solid green;
}
.block-sibling:after {
  content: 'Block sibling';
  color: green;
}
.float {
  float: left;
  border: 3px solid red;
  height: 90px;
  width: 150px;
  z-index: 1;
}
.float:after {
  content: 'Float';
  color: red;
}
Run Code Online (Sandbox Code Playgroud)
<div class="float"></div>
<div class="block-sibling">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor.
</div>
Run Code Online (Sandbox Code Playgroud)

这也在10.6计算高度和边距中指定.对于"普通"块,

只考虑正常流量的儿童(即浮动框和绝对定位的框被忽略[...])

在此输入图像描述

html {
  width: 550px;
  border: 1px solid;
}
body {
  font-family: sans-serif;
  color: rgba(0,0,0,.15);
}
body:after {
  content: '';
  display: block;
  clear: both;
}
div {
  position: relative;
}
div:after {
  font-size: 200%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}
.block-parent {
  border: 3px solid blue;
}
.block-parent:after {
  content: 'Block parent';
  color: blue;
}
.float {
  float: left;
  border: 3px solid red;
  height: 130px;
  width: 150px;
}
.float:after {
  content: 'Float';
  color: red;
}
Run Code Online (Sandbox Code Playgroud)
<div class="block-parent">
  <div class="float"></div>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
</div>
Run Code Online (Sandbox Code Playgroud)

Hacky解决方案:清除

解决问题的一种方法是强制将一些流入元素放置在所有浮点下面.然后,父级的高度将增长以包裹该元素(因此也包括浮点数).

这可以使用以下clear属性实现:

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

在此输入图像描述

html {
  width: 550px;
  border: 1px solid;
}
body {
  font-family: sans-serif;
  color: rgba(0,0,0,.15);
}
body:after {
  content: '';
  display: block;
  clear: both;
}
div {
  position: relative;
}
div:after {
  font-size: 200%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}
.block-parent {
  border: 3px solid blue;
}
.block-parent:after {
  content: 'Block parent';
  color: blue;
}
.float {
  float: left;
  border: 3px solid red;
  height: 84px;
  width: 150px;
}
.float:after {
  content: 'Float';
  color: red;
}
.clear {
  clear: both;
  text-align: center;
  height: 37px;
  border: 3px dashed pink;
}
.clear:after {
  position: static;
  content: 'Block sibling with clearance';
  color: pink;
}
Run Code Online (Sandbox Code Playgroud)
<div class="block-parent">
  <div class="float"></div>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra.
  <div class="clear"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

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

<div style="clear: both"></div>
Run Code Online (Sandbox Code Playgroud)

但是,这不是语义上的.所以最好在父节点的末尾生成一个伪元素:

.clearfix::after {
  clear: both;
  display: block;
}
Run Code Online (Sandbox Code Playgroud)

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

解决方案:BFC根源

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

根据块格式化上下文根的10.6.7"自动"高度,

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

在此输入图像描述

html {
  width: 550px;
  border: 1px solid;
}
body {
  font-family: sans-serif;
  color: rgba(0,0,0,.15);
}
body:after {
  content: '';
  display: block;
  clear: both;
}
div {
  position: relative;
}
div:after {
  font-size: 200%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}
.block-parent {
  border: 3px solid blue;
}
.block-parent.bfc-root:after {
  content: 'BFC parent';
  color: blue;
}
.float {
  float: left;
  border: 3px solid red;
  height: 127px;
  width: 150px;
}
.float:after {
  content: 'Float';
  color: red;
}
.bfc-root {
  overflow: hidden;
}
Run Code Online (Sandbox Code Playgroud)
<div class="block-parent bfc-root">
  <div class="float"></div>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
</div>
Run Code Online (Sandbox Code Playgroud)

另外,如9.5 Floats所述,BFC根也是有用的,因为以下内容:

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

在此输入图像描述

html {
  width: 550px;
  border: 1px solid;
}
body {
  font-family: sans-serif;
  color: rgba(0,0,0,.15);
}
body:after {
  content: '';
  display: block;
  clear: both;
}
div {
  position: relative;
}
div:after {
  font-size: 200%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}
.block-sibling {
  border: 3px solid green;
}
.block-sibling.bfc-root:after {
  content: 'BFC sibling';
  color: green;
}
.float {
  float: left;
  border: 3px solid red;
  height: 90px;
  width: 150px;
  z-index: 1;
}
.float:after {
  content: 'Float';
  color: red;
}
.bfc-root {
  overflow: hidden;
}
Run Code Online (Sandbox Code Playgroud)
<div class="float"></div>
<div class="block-sibling bfc-root">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
</div>
Run Code Online (Sandbox Code Playgroud)

块格式化上下文由.建立

注意那些可能具有不期望的附带效果,例如剪切溢出内容,使用缩小到适合算法计算自动宽度,或者变得不流动.所以问题在于,不可能有一个具有可见溢出的流内块级元素来建立BFC.

显示L3解决了这些问题:

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

可悲的是,目前还没有浏览器支持.最终我们可以使用

.bfc-root {
  display: flow-root;
}
Run Code Online (Sandbox Code Playgroud)


小智 19

把你的浮动div(s)放在一个div和CSS中给它overflow:hidden;
它将工作正常.


小智 15

W3Schools推荐:

放置overflow: auto父元素,它将"着色"整个背景,包括元素边距.浮动元素也将留在边界内.

http://www.w3schools.com/css/tryit.asp?filename=trycss_layout_clearfix


Luc*_*ter 11

没有什么遗漏.Float是为您希望图像(例如)放在几段文本旁边的情况而设计的,因此文本会在图像周围流动.如果文本"拉伸"容器,那就不会发生.您的第一段将结束,然后您的下一段将在图像下方开始(可能在下方几百个像素).

这就是为什么你得到的结果.

  • 这与浮动元素如何正确拉伸父母的高度有什么关系? (3认同)

LSe*_*rni 9

在某些情况下,即当(如果)您只是使用float元素在同一"线"上流动时,您可能会使用

display: inline-block;
Run Code Online (Sandbox Code Playgroud)

代替

float: left;
Run Code Online (Sandbox Code Playgroud)

否则,clear在最后使用一个元素工作,即使它可能违背谷物需要一个元素来做应该是CSS的工作.


pen*_*fox 8

这是更现代的方法:

.parent {display: flow-root;} 
Run Code Online (Sandbox Code Playgroud)

没有更多明确的修正.

ps使用overflow:hidden; 隐藏盒子阴影所以......


Fly*_*t91 7

谢谢你LSerni你为我解决了.

为达到这个 :

+-----------------------------------------+
| +-------+                     +-------+ |
| | Text1 |                     | Text1 | |
| +-------+                     +-------+ |
|+----------------------------------------+
Run Code Online (Sandbox Code Playgroud)

你必须这样做:

<div style="overflow:auto">
    <div style="display:inline-block;float:left"> Text1 </div>
    <div style="display:inline-block;float:right"> Text2 </div>
</div>
Run Code Online (Sandbox Code Playgroud)


Sam*_*ton 5

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

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