浮动最初的定义:实现文本环绕图片的效果。除此之外,没有其他方法可实现。
什么是浮动?
css
中的浮动是用float
属性来定义:float: left | right | none | inline-start | inline-end
float
值不为none
,会对display
属性的值产生影响:
inline-block、inline、block
->block
table-*
->block
inline-table、table
->table
flex、inline-flex
-> 值不变,但是float
对这样的元素不起作用- 其他值不变
当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。浮动元素不属于文档中的普通流,属于浮动布局。 (CSS
三种基本的定位机制:普通流、浮动和绝对定位)
浮动的元素不会影响到普通流的块级元素的布局(如同浮动元素不存在一样),只会影响内联元素(如:文本环绕)的排列,如下图2所示。当浮动元素高度超出父元素的时候,就会出现父元素不会自动伸高来闭合浮动元素(高度塌陷现象)。顾名思义,浮动就是漂浮于普通流之上,像浮云一样,但是只能左右浮动。
<section class="flex_box2">
<div class="flex_item2">
<div class="img"><img src="./img/pins_3333913039.webp"></div>
<div class="color"></div>
</div>
<div class="flex_item2">
<img src="./img/pins_3333913039.webp">
<div class="text">读书,去别人的灵魂里偷窥。旅行,去陌生的环境里去感悟。电影,去荧屏里感受别人的生活历程。冥想,去自己内心的秘境里探寻。<br/>读书,去别人的灵魂里偷窥。旅行,去陌生的环境里去感悟。电影,去荧屏里感受别人的生活历程。冥想,去自己内心的秘境里探寻。</div>
</div>
</section>
<style>
.flex_box2 {
font-size: 0;
}
.flex_item2 {
padding: 20px;
border: 1px solid #0aa;
box-sizing: border-box;
vertical-align: top;
}
.flex_item2 .img,
.flex_item2 img {
float: left;
width: 100px;
margin-left: 20px;
margin-right: 20px;
}
.flex_item2 .img > img {
width: 100%;
}
.flex_item2 .color {
height: 50px;
margin-top: 5px;
background: #0aa;
}
.flex_item2 .text {
font-size: initial;
}
</style>
浮动造成影响
- 会对相邻的元素(紧邻浮动元素后面的元素)产生影响。
如果相邻元素是块级元素会无视这个浮动的块框(如上图中的背景色模块),也就是我们平时看到的效果——使到自身尽可能与这个浮动元素处于同一行,导致被浮动元素覆盖。
如果相邻元素是内联元素,则会尽可能围绕浮动元素(如上图中的文案模块)。
- 父元素在获取高度计算时,会忽略浮动元素,即不计算浮动元素高度。这就是浮动塌陷,也称高度塌陷现象。
什么是块级格式化上下文?
块格式化上下文(Block Formatting Context,BFC) 是Web
页面的可视CSS
渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
BFC,主要用于对块级元素排版。创建了 BFC
的元素就是一个独立的盒子(HTML
中的一个盒子, 看不见而已),里面的子元素不会在布局上影响外面的元素,同样,外面的元素,也不会影响其子元素。
从这一点来说,块级格式化上下文的特性与层叠上下文(css探索系列之CSS层叠)类似。
下列方式会创建块格式化上下文:
- 根元素:<
html
> - 浮动元素:
float
不为none
- 绝对定位元素:
position
不为static | relative
overflow
值不为visible
的块元素- 行内块元素:
display: inline-block
- 表格单元格:
display: table-cell
。HTML
表格单元格默认为该值 - 表格标题:
display: table-caption
。HTML
表格标题默认为该值 - 匿名表格单元格元素:
display: table | inline-table | table-row | table-row-group | table-header-group | table-footer-group
display: flow-root
。一个新的display
属性的值,它可以创建无副作用的 BFC。注:Safari
不支持。- 弹性元素:
display: flex | inline-flex
元素的直接子元素 - 网格元素:
display: grid | inline-grid
元素的直接子元素 contain: layout | content | paint
- 多列容器:
column-count
或column-width
不为auto
、column-count: 1
column-span: all
。即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。
注意:display: table
本身并不会创建BFC
,但是它会产生匿名盒子(anonymous boxes
),而匿名盒子中的display: table-cell
可以创建新的BFC
,换句话说,触发块级格式化上下文的是匿名框,而不是display: table
。所以通过display:table
和display: table-cell
创建的BFC效果是不一样的。
块级格式化上下文的特性
块格式化上下文对浮动定位(float)、清除浮动(clear)、外边距折叠(Margin collapsing)都很重要。浮动定位和清除浮动时只会应用于同一个BFC
内的元素。外边距折叠(Margin collapsing)也只会发生在属于同一BFC
的块级元素之间。
块级格式化上下文的三个特性:
- BFC会阻止外边距折叠(CSS探索系列之Margin)
当两个相邻的块框在同一个块级格式化上下文中时,它们之间垂直方向的外边距会发生叠加。换句话说,如果这两个相邻的块框不属于同一个块级格式化上下文,那么它们的外边距就不会叠加。
根据规定,一个块级格式化上下文的边框不能和它里面的元素的外边距重叠。由于这个原因,当给一个挨着浮动的块级格式化上下文添加负的外边距时将会不起作用
- BFC不会重叠浮动元素
BFC
内的浮动不会影响其它BFC
中元素的布局,而清除浮动只能清除同一BFC
中在它前面的元素的浮动。 - BFC通常可以包含浮动,即计算
BFC
的高度时,浮动元素也参与计算独立的块级上下文可以包裹浮动流,全部浮动子元素也不会引起容器高度塌陷,也就是说父元素会把浮动元素的高度也计算在内,所以不用清除浮动来撑起高度。同时
BFC
任然属于文档中的普通流。因此,父元素创建了新的BFC,可以闭合浮动
什么是hasLayout?
hasLayout
是ie
私有的概念,ie7
及更低版本的ie
浏览器不支持BFC
,但我们可以针对ie7、6
浏览器加入对应的hasLayout
规则来实现BFC
的效果!
IE
使用Layout
概念来控制元素的尺寸和位置。可以用Javascript
函数hasLayout
查看一个元素是否拥有Layout
,返回true | false
。如果一个元素有Layout
,它就有自身的尺寸和位置;如果没有,它的尺寸和位置由最近的拥有布局的祖先元素控制。
hasLayout
是一个只读属性,所以无法使用Javascript
进行设置。它的值为true
的时候会达到和BFC
类似的效果。
以下方法可以使元素hasLayout
为true
:
position: absolute
float: left | right
display: inline-block
- width: 除
auto
外的任意值 - height: 除
auto
外的任意值 - zoom: 除
normal
外的任意值 writing-mode: tb-rl
- IE7中
overflow: hidden|scroll|auto
怎样清除浮动呢?
清除浮动,也可以称为闭合浮动。两者实质上,都是为了消除浮动塌陷。它们的区别在于:
清除浮动:对应的单词是 clear
,对应CSS
中的属性是 clear:left | right | both | none
,只能清除同一BFC
中在它前面的元素的浮动。
闭合浮动:更确切的含义是使浮动元素闭合,即创建BFC
,从而消除浮动塌陷。
确切的说,我们想要达到的效果是闭合浮动,而不是单纯的清除浮动。单纯的清除浮动,并不能解决容器高度塌陷的问题。
比如:我们将上一个示例的背景色模块,加上样式clear: both
清除浮动,该模块的浮动还是会影响其后面的兄弟元素。如下图3:
<section class="flex_box2">
<div class="flex_item2" style="clear: both;">
<div class="img"><img src="./img/pins_3333913039.webp"></div>
<div class="color"></div>
</div>
...
</div>
</section>
再如:我们将上一个示例的背景色模块,加上样式display: flow-root
闭合浮动,创健了新 BFC
,那么,它就不会影响其他 BFC
的元素了。如下图4:
<section class="flex_box2">
<div class="flex_item2" style="display: flow-root">
<div class="img"><img src="./img/pins_3333913039.webp"></div>
<div class="color"></div>
</div>
...
</div>
</section>
三种清除浮动的方法
方法一(摧荐): 父元素加伪元素,并给伪元素加clear:both
,据说是最高大上的方法
优点:浏览器支持好,不容易出现怪问题
缺点:注意浏览器兼容问题
<!--定义一个通用清除浮动的样式,在需要的元素中加上-->
<style>
.clear_float {
zoom: 1; /*对IE6/7的兼容处理,触发 hasLayout*/
}
.clear_float:after,
.clear_float::after {
display: block;
width: 0;
height: 0;
content:' ';
visibility: hidden;
clear: both;
}
</style>
<section class="flex_box2">
<div class="flex_item2 clear_float"> ... </div>
<div class="flex_item2"> ... </div>
</section>
方法二:浮动元素后,新增空标签div
,并设置样式clear:both
优点:通俗易懂,容易掌握
缺点:将添加很多无意义的空标签
<section class="flex_box2">
<div class="flex_item2"> ... </div>
<div style="clear: both;"></div>
<div class="flex_item2"> ... </div>
</section>
方法三:浮动元素后,新增空标签br
标签,并设置属性clear="both"
。与方法二类似
<section class="flex_box2">
<div class="flex_item2"> ... </div>
<br clear="both" />
<div class="flex_item2"> ... </div>
</section>
闭合浮动的方法
为浮动元素的父元素创建 BFC
(为兼容ie6
,还需触发hasLayout
,如加: zoom: 1
)。比如:
- (推荐)
display: inline-block
。注意设置width: 100%
。 overflow: auto | hidden | visible
。据说auto
对seo
比较友好,hidden
对seo
不是太友好,但切记不能使用visible
值。缺点:内部元素宽高超过父元素时,会出现滚动条(scroll)或者隐藏溢出部分(hidden)。float: left | right
。缺点:使得与父元素相邻的元素的布局会受到影响,不可能一直浮动到body
。display: table
。缺点:盒模型属性已经改变,由此造成的一系列问题,得不偿失。display: flow-root
。一个新的display
属性的值,它可以创建无副作用的 BFC。缺点:Safari
不支持。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。