在css中,是存在流的概念的。在正常情况下,页面总是从左到右,从上到下布局,这种被称为正常的流。
但是有很多排版,正常流是没办法实现的,因此我们需要一些手段来破坏流,从而实现一些特殊的布局,而float就具备破坏流的特性。
float 设计的初衷
很多新手在布局的时候,总喜欢用float来实现。例如一个三栏布局,左右固定,中间自适应,有些人会通过float来一列一列把它们砌起来。这样的布局极其容易崩溃,只要高度或者宽度稍微有些变化,整个页面都会错乱。
因此float设计的初衷并不是用来布局的,其本意仅仅是实现图片文字环绕效果,即图片左浮动,文字环绕图片,如下图所示:
.float {
width: 150px;
float: left;
}
.content {
width: 400px;
}
<img src="./card.jpg" alt="" class="float" />
<p class="content">
文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕
</p>
float 的特性
包裹性
包裹指的是一个浮动元素,如果子元素宽度比100%的宽度小,则浮动元素的宽度就是该子元素的宽度,如下所示:
原本 P 标签的宽度应该是100%,子元素的宽度 160px,设置浮动之后 P 标签的宽度是 160px了,这就是包裹性。
破坏文档流
这是float最本质的特性:破坏文档流。
下面是正常从上到下排列的代码:
<div class="father">
<div class="first">
文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕
</div>
<div>这是第二段</div>
</div>
当设置div.first为float之后,我们看看排列情况:
可以看到后面的div浮动上去了,相当于前面的div脱离了文档流,悬浮起来了,不占据文档流的位置了。
所以,就形成了文字环绕的效果,这也是float设计的初衷。
float元素还会导致父级高度塌陷,你可以这么理解,只有父级高度塌陷后面的内容才会浮动上去。如下图:
但是仅仅是这样还是不可以形成图片环绕效果的,不然文字浮上来就只会覆盖在图片上面。这里面还隐藏着一个特性:行框盒子和浮动元素的不可重叠性。这点是与定位元素最大的不同,就是浮动元素不会和其他元素重叠,但是定位元素会发生重叠。
意思是说行框盒子和浮动元素不会发生重叠,因此,下面的文字浮上去之后才不会被覆盖。即使我们给文字设置margin负值也不会起作用。
总之,就是背景可以重叠,但是内容不重叠。其实还是整个元素往上浮动了。
总结:浮动元素会脱离原来的文档流,后面的元素替补进去;同时,浮动元素不会覆盖替补进去元素的内容。
块状格式化上下文 BFC
设定了float的元素,其display的最终值会表现为block或者table。因此,设置了float的元素,下面的写法是多余的:
.float {
float: left;
display: block; /* 多余 */
}
.float {
float: left;
vertical-align: middle; /* 不起作用 */
}
BFC
BFC(Block Formatting Context)块级格式化上下文,是Web页面中盒模型布局的CSS渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。
形成BFC的条件:
- 浮动元素,float 除 none 以外的值
- 定位元素,position(absolute,fixed)
- display 为以下其中之一的值 inline-block,table-cell,table-caption
- overflow 除了 visible 以外的值(hidden,auto,scroll)
BFC的特性:
- bfc的区域不会与float的元素区域重叠,可以用来排版。
以常见的两栏布局为例,左边固定宽度,右边不设宽,因此右边的宽度自适应,随浏览器窗口大小的变化而变化。
.column:nth-of-type(1) {
float: left; /*创建bfc */
width: 200px;
height: 300px;
margin-right: 10px;
background-color: red;
}
.column:nth-of-type(2) {
overflow: hidden; /*创建bfc */
height: 300px;
background-color: purple;
}
<div class="column"></div>
<div class="column"></div>
三栏布局,左右两边固定宽度,中间不设宽,因此中间的宽度自适应,随浏览器的大小变化而变化。
.column:nth-of-type(1),
.column:nth-of-type(2) {
float: left;
width: 100px;
height: 300px;
background-color: green;
}
.column:nth-of-type(2) {
float: right;
}
.column:nth-of-type(3) {
overflow: hidden; /*创建bfc*/
height: 300px;
background-color: red;
}
<div class="contain">
<div class="column"></div>
<div class="column"></div>
<div class="column"></div>
</div>
- 计算bfc的高度时,浮动元素也参这与计算,就可以清除浮动。
这个是大家再熟悉不过的了,利用overflow:hidden清除浮动,因为浮动的盒子无法撑出处于标准文档流的父盒子的height。现在计算bfc的高度时,浮动元素也参这与计算,所以就能清除浮动了。
- bfc就是页面上的一个独立容器,容器里面的子元素不会影响外面元素。
我们知道float可以用来形成文字环绕的效果,即浮动的盒子会遮盖下面的盒子,但是下面盒子里的文字是不会被遮盖的,文字反而还会环绕浮动的盒子。
但如果我不想文字环绕呢,如下图:
这里就可以利用 BFC 来使右边的盒子成为一个独立的区域,左右互补影响:
.left {
float: left;
width: 100px;
height: 100px;
background-color: yellow;
}
.right {
background-color: green;
overflow: hidden;
}
加了overflow: hidden;之后,右边内容的宽度是1324px。如果不加呢?
可以看到宽度是1424px,也就是左边的盒子覆盖了右边的盒子,只是没有覆盖到文字而已。
这就是 BFC 形成了一个独立的空间。