为什么如果容器元素包含了浮动元素,容器元素的高度不会增加?
为什么容器元素的高度不会增加,即使它包含了浮动的元素?
问题的原因是,浮动元素不会撑开其父容器的高度,导致父容器的高度无法自动适应内部浮动元素的高度。
解决方法是在父容器中添加overflow:auto
属性。这样可以触发BFC(块格式化上下文),使得父容器可以包含浮动元素。
以下是代码示例:
点击此处查看jsFiddle示例。
某些情况下,使用overflow:auto
会隐藏超出边界的内容。但实际上,只有当内部浮动元素的内容超过父容器的高度时,才会出现内容被隐藏的情况。
点击此处查看一个示例,展示了使用overflow:auto
后,内容不会被隐藏。
以上就是为什么容器元素的高度不会增加,以及解决方法的说明。如果所有问题都能像这样简单解决,那就不需要其他复杂的方法了。
在遇到浮动元素时,容器元素的高度为什么不会增加呢?这个问题的出现是由于以下原因,并且有两种解决方法。
首先,正常情况下,假设没有设置显式的高度,一个块级元素(比如div)的高度会根据其内容来设置。父级div的底部会延伸到最后一个元素之外。然而,浮动元素会阻止父级在确定高度时将浮动元素考虑在内。这意味着如果最后一个元素是浮动的,它将不会像普通元素一样"拉伸"父级元素。
解决这个问题有两种常见方法。
第一种方法是添加一个"清除"元素,也就是在浮动元素下面添加另一个元素来强制父级元素拉伸。所以在最后一个子元素后面添加以下HTML代码:
这个元素不应该可见,并且通过使用`clear:both`,确保它不会与浮动元素并排,而是在其后面。
第二种方法,是大多数人(我认为)更喜欢的方法,是通过改变父元素的CSS,使`overflow`属性不是"visible"。将`overflow`设置为"hidden"会强制父级元素在浮动子元素之外延伸。当然,这只适用于没有设置父元素高度的情况。
就像我说的,第二种方法更受青睐,因为它不需要你去添加语义上没有意义的元素到你的标记中。但是有时候你需要`overflow`是可见的,这种情况下添加一个清除元素是完全可以接受的。
为什么容器元素的高度不会增加,即使它包含了浮动元素?
浮动的元素不会增加容器元素的高度,因此如果您不清除它们,容器的高度就不会增加...
我用图形来展示给你看:
更多解释:
<div>
<div style="float: left;"></div>
<div style="width: 15px;"></div> <!-- 这个将会和上面的div并排,为什么?因为上面的div浮动了,所以剩下的空间变成了空白 -->
<div style="clear: both;"></div>
<!-- 现在为了防止下一个div浮动到上面的div旁边,我们使用`clear: both;`。这个像是一堵墙,所以现在在这个点之后没有任何的div会浮动。容器的高度现在也会包括这些浮动的div的高度 -->
<div></div>
</div>
您也可以在容器元素上添加overflow: hidden;
,但我建议您使用clear: both;
。
另外,如果您想要自行清除一个元素,您可以使用以下代码:
.self_clear:after { content: ""; clear: both; display: table; }
CSS中的float是如何工作的?
浮动是什么以及它的作用是什么?
- 大多数初学者都对
float
属性存在误解。那么,float
到底是做什么的呢?最初,float
属性是为了使文本围绕浮动的图片展示,这些图片可以是left
或者right
浮动的。详情参见Uchicha的另一个解释。那么,如果使用float
属性将盒子放在一起是不是错误的呢?答案是否定的;如果用float
属性将盒子放在一起是没有问题的。 - 将
inline
或者block
级别的元素浮动会使该元素表现得像一个inline-block
元素。演示 - 如果您将一个元素向
left
或者right
浮动,那么该元素的宽度将被限制为它所包含的内容的宽度,除非显式地定义了width
... - 您不能将一个元素
center
浮动。这是我经常看到初学者犯的最大的错误,使用float: center;
,这不是float
属性的有效值。一般来说,float
用于将内容向左或者右浮动/移动。有效的float
属性只有四个值,即left
,right
,none
(默认值)和inherit
。 - 当父元素包含浮动的子元素时,父元素会折叠,为了防止这种情况发生,我们使用
clear: both;
属性来清除两侧的浮动元素,这样可以防止父元素折叠。详情请参见我的另一个答案这里。 - (重要)想象一下我们有一个堆叠的各种元素。当我们使用
float: left;
或者float: right;
时,该元素会上移一层。因此,正常文档流中的元素会隐藏在浮动元素的后面,因为它在堆叠中位于浮动元素上方一层。(请不要将此与z-index
相关联,因为它完全不同。)
以一个案例为例,解释CSS浮动是如何工作的,假设我们需要一个简单的两列布局,其中包含一个页眉、页脚和两列内容,下面是布局的蓝图...
在上面的例子中,我们只对红色的方框进行浮动,可以将它们都向左浮动,也可以将一个向左浮动,另一个向右浮动,这取决于布局,如果是3列,可以将2列向左浮动,另一列向右浮动,所以取决于布局,但在这个例子中,我们只有一个简化的2列布局,所以将一个向左浮动,另一个向右浮动。
下面是创建布局所需的标记和样式进一步解释...
<div class="main_wrap">
<header>Header</header>
<div class="wrapper clear">
<div class="floated_left">
This<br />
is<br />
just<br />
a<br />
left<br />
floated<br />
column<br />
</div>
<div class="floated_right">
This<br />
is<br />
just<br />
a<br />
right<br />
floated<br />
column<br />
</div>
</div>
<footer>Footer</footer>
</div>
* {
-moz-box-sizing: border-box; /* 仅用于演示目的 */
-webkkit-box-sizing: border-box; /* 仅用于演示目的 */
box-sizing: border-box; /* 仅用于演示目的 */
margin: 0;
padding: 0;
}
.main_wrap {
margin: 20px;
border: 3px solid black;
width: 520px;
}
header, footer {
height: 50px;
border: 3px solid silver;
text-align: center;
line-height: 50px;
}
.wrapper {
border: 3px solid green;
}
.floated_left {
float: left;
width: 200px;
border: 3px solid red;
}
.floated_right {
float: right;
width: 300px;
border: 3px solid red;
}
.clear:after {
clear: both;
content: "";
display: table;
}
让我们逐步理解布局并了解浮动是如何工作的...
首先,我们使用主要包装元素,你可以认为它就是你的视口,然后我们使用header
并指定height
为50px
,所以没有什么特别的。它只是一个正常的非浮动块级元素,除非它被浮动或者我们为其指定inline-block
。
第一个有效值为left
,所以在我们的例子中,我们对.floated_left
使用float: left;
,所以我们打算将一个块向左浮动到我们的容器元素的左侧。
是的,如果你看到了,父元素,也就是带有绿色边框的那个,没有展开,你看到的只是一个没有扩展的绿色边框,但它应该展开,对吗?稍后我们会回到这个问题,现在我们已经得到了一个向左浮动的列。
接下来是第二列,让我们将其向右浮动。
在这里,我们有一个宽度为300px
的列,我们将其向右浮动,它将位于左侧浮动的列旁边,由于它向左浮动,它在右侧创建了一个空的间距,由于右侧有足够的空间,我们的右浮动元素完美地位于左侧的元素旁边。
然而,父元素仍然被折叠了,好吧,现在让我们来修复它。有很多方法可以防止父元素折叠。
- 在父元素结束之前添加一个空的块级元素,并在之前使用
clear: both;
,这个方法可以清除浮动元素,可以做到这一点,但我建议不要这样做。
在.wrapper
的结束标签之前添加<div style="clear: both;"></div>
,例如
<div class="wrapper clear">
<!-- 浮动的列 -->
<div style="clear: both;"></div>
</div>
好吧,这样修复得很好,没有折叠的父元素了,但它会向DOM添加不必要的标记,所以有些人建议在包含浮动子元素的父元素上使用overflow: hidden;
,这样可以实现预期的效果。
在.wrapper
上使用overflow: hidden;
.wrapper { border: 3px solid green; overflow: hidden; }
这样可以节省一个元素,每次需要clear
浮动时,不需要添加overflow: hidden;
,但是当我进行了各种测试时,它在某种情况下失败了,这种情况是在子元素上使用box-shadow
时。
演示(无法在所有四个边上看到阴影,overflow: hidden;
引起了这个问题)
那么现在怎么办?节省一个元素,没有overflow: hidden;
,所以采用清除浮动的方法,将下面的代码片段添加到您的CSS中,并且正如您在父元素上使用overflow: hidden;
一样,在父元素上调用下面的class
进行自清除。
.clear:after {
clear: both;
content: "";
display: table;
}
<div class="wrapper clear">
<!-- 浮动的元素 -->
</div>
在这里,阴影按预期工作,并且自动清除了父元素,防止折叠。
最后,我们在清除浮动的子元素后使用页脚。
什么时候会使用float: none;
,毕竟它是默认值,因此声明float: none;
有什么用呢?
这取决于情况,如果您正在进行响应式设计,您将经常使用这个值,当您希望您的浮动元素在某个分辨率下一行一个时。在这种情况下,float: none;
属性起着重要的作用。
一些CSS浮动有用的实际示例。
- 我们已经看到的第一个示例是创建一个或多个列布局。
- 在
p
标签中浮动img
,使得内容可以环绕它。
演示(没有浮动的img
)
演示2(img
向left
浮动)
- 使用浮动创建水平菜单 - 演示
浮动第二个元素,或者使用`margin`
最后但并非最不重要的是,我想解释一下这种情况,当您只将一个元素向左浮动,而不对另一个元素浮动时,会发生什么?
假设我们从.floated_right
的class
中移除float: right;
,div
将会从极左侧开始渲染,因为它没有被浮动。
所以在这种情况下,要么您可以将其向左浮动
或者
浮动元素不会增加块级父元素的高度的事实在规范中明确说明了:w3.org/TR/CSS21/visudet.html#normal-block,之所以添加清除浮动可以起作用,是因为1)清除浮动通常在正常流中,2)清除浮动要求清除浮动的元素位于浮动元素的底部,3)容器必须被拉伸以包含清除浮动元素。
它的标题太宽泛了,而且会误导人们将任何浮动问题都关闭为重复问题。这里的问题只涵盖了一个方面:容器是否包裹浮动元素。
无论如何,技术性质的解释与clear: both;
的解释是一样的,但如果您觉得这样的编辑是合理的,那么就保持原样吧。
非常好的回答。"将任何元素向左或向右浮动,元素的宽度将被限制为它所包含的内容的宽度,除非显式地定义了宽度" - 我观察到了同样的事情,只是想要确认一下。谢谢。
<div style="clear: both;"></div>在这种情况下更像是一个技巧。实际上,这个div没有语义上的意义,只是用于样式化的html标签。
overflow: hidden;
对我有用,因为我的浮动属性是由js动态更改的,这是一个有帮助的解决方法。