本文目录:
float
的特性
浮动机制
float
实现流体布局
float
与absolute
的区别
float
与inline-block
清除浮动的方法及优缺点
1. float的特性
一个元素设置了float
属性,会表现出如下特性:
- 包裹性
- 破坏文档流
- 块状格式化上下文
- 没有margin合并
文字环绕(设计初衷)
float
最早的设计目的是用于图片,使文字能够环绕在图片周围,像下面这样:
文字环绕效果是很明显的,这里要注意一个地方:浮动的块虽然脱离了正常的文档流,但是还会占有正常文档流的文本空间,可以看到上面第二种图,p的区域其实是顶到了img的底下的,因为float
让img
脱离文档流,但是p
上的文字却没有顶过去,也就是说p上的一部分文字空间仍然被img占据着,所以从这里也可以看出float
的脱离文档流不是完全脱离。
包裹性
包裹性包含了包裹和自适应两个特性。
所谓的包裹性是指,使用float
的元素会自动加上一个块级框,也就是可以像块级元素那样设置宽高,例子如下:
如果子元素宽度足够小,则浮动元素的宽度就是该子元素的宽度,如下所示:
.float {
float: left;
}
<p class="float">
<span>这是浮动元素的子元素</span>
</p>
自适应指的是如果浮动元素的父元素有设置宽度,并且浮动元素的子元素宽度超出了父元素,则浮动元素的宽度最终表现为父元素的宽度,如下所示:
.father {
width: 100px;
}
.float {
float: left;
}
<div class="father">
<p class="float">
<span>这是浮动元素的子元素</span>
</p>
</div>
块状格式化上下文
设定了float的元素,其display的最终值会表现为block或者table,具体转换如下表:
因此,设置了float的元素,下面的写法是多余的:
.float {
float: left:
display: block;
}
.float {
float: left;
vertical-align: middle; /* 不起作用 */
}
格式化上下文属于BFC的内容。
破坏性
这是float
最本质的特性,,float
的破坏性主要是指它会使父容器的高度塌陷,也就是父元素在高度计算的时候会忽略浮动的元素
.float {
float: left;
}
<div class="father">
<img src="./card.jpg" alt="" class="float">
</div>
<p>
文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕
</p>
可以看到,父元素的高度为0,但这不是bug,而是float本身就是这样设计的,因此只有让父元素高度塌陷了,后面的元素才有机会浮上来。但是仅仅是这样还是不可以形成图片环绕效果的,不然文字浮上来就只会覆盖在图片上面。这里面还隐藏着一个特性:
- 行框盒子和浮动元素的不可重叠性
意思是说行框盒子和浮动元素不会发生重叠,因此,下面的文字浮上去之后才不会覆盖在图片之上。即使我们给文字设置margin负值也不会起作用。
没有margin合并
设置了float的元素,由于形成了BFC,因此也就没有了margin合并。
2.浮动机制
我们先来看个例子:
.float {
float: right;
}
<div>
<span>标题</span>
<a class="float">链接</a>
</div>
在标准浏览器下,“标题”和“链接”会在同一行展示,并且“链接”会浮动在右边。但是如果“标题”非常长,一行放不下呢,“链接”是浮动在第一行还是第二行呢?答案是第二行,要想解释这个,我们得先理解两个概念,一个是“浮动锚点”,一个是“浮动参考”:
- 浮动锚点是float元素所在的“流”中的一个点,这个点本身并不浮动,表现得就像是一个没有margin、padding和border的空的内联元素。
- 浮动参考指的是浮动元素对齐参考的实体。
float元素的“浮动参考”是行框盒子,也就是float元素在当前“行框盒子”内定位,因此,上面的例子“链接”会在第二行展示。但是也有一种情况是,浮动元素前后并没有内联元素,因此也就不存在行框盒子,这时候就是“浮动锚点”在起作用。因为“浮动锚点”表现得像一个内联元素,有内联元素,自然就有行框盒子,只是这个盒子看不见也摸不着罢了。
3.float实现流体布局
前面文字环绕的例子,只要稍微改造一下就可以实现两栏或多栏的自适应布局,代码如下:
.father {
overflow: hidden;
height: 200px;
}
.float {
float: left;
width: 100px;
}
.content {
margin-left: 120px;
}
<div class="father">
<img src="./card.jpg" alt="" class="float">
<p class="content">文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕文字环绕</p>
</div>
4. float和position:absolute
脱离文档流
虽然在我们常常看到描述float
和absolute
的时候,都陈伟脱离文档流,但是实际上并不完全相同:
在脱离文档流方面,absolut
正如它的名字一般,是绝对脱离,设置了该属性的元素,将完全独立在文档流之外,不会对其他的元素产生任何影响,就举上面文字环绕的例子来说,如果把img
属性的float
换成position:absolue
属性的话,那么p元素以及上面的文字都会顶到图片的位置上,就像这样:
而对于float
我们之前已经提出,float
只是脱离了文档流的dom
空间但是还占据着文字空间(这两个名词不知道是否已经有更标准的词语出现,在这里只是个人用法,见谅)
高度塌陷
float
和absolute
都能引起父元素的高度塌陷,同样地,由于absolute
是完全脱离文档流,所以这种情况的高度塌陷是没办法清除的;float
引起的高度塌陷则是可清除的,我们常说的清除浮动就是指清除float
带来的高度塌陷问题,在下文会有提到。
在两列布局中的使用
float
和absolute
都被广泛用于两列布局之中,absolute
由于完全脱离,可以做到精准的定位,但是不利于设计两列之间的联动变化;float
属性可以保留一些相互影响,但是要非常小心传递来的问题,比如clear
的不当使用会导致左右布局异常联动,在后面讲清除浮动时会专门讲解。而且在使用浮动布局的时候,要注意某些情况下要交换浮动左右浮动元素的声明次序
5. float和display:inline-block
横向排列
首先,使用float
和inline-block
都能使li
横向排列。但是,使用float
可以选择排列的方向,而inline
只有一种方向;
第二是在单纯排列图片的时候,如果图片大小不是完全一致的,那么使用这两个属性都能完成比较合适的排列:
但是如果图片大小不等高,float
的脱离文档流特性导致排列的某些图片会被挤到下一行,导致垂直方向无法对齐,如下:
而如果使用display:inline-block
则可以保证垂直方向的对齐:
所以如果是要保证垂直对齐的情况下,使用display:inline-block
会比较合适
float
和displayinline-block
这两个属性有一个很经常用到的地方就是横向导航。导航中一般是单行对齐,而且除了图片之外还有文字,这时候如果采用display:inline-block
, 必须要考虑display:inline-block
属性带来的空白间隙问题(这个问题可以自行查找,本文中不赘述),此时使用float:left
更为合适一些。