先来一个常见的bug:
代码:
效果:
描述:当我们给一个元素设置float浮动之后,其后面的元素不再按照正常的排列方式跟随在这个元素后面,而是会被float元素压在下面,并且float元素不再作为撑开父元素的子元素。那么为什么会出现这样的问题呢?可显而知是浮动元素带来的影响,那么浮动元素布局的时候为什么会出现这样的影响呢?接下来我们来探究一下浮动元素的问题
一.float的本质
首先我们来探究一下float的本质,float的出现其实是为了实现文字环绕的效果的,类似于如下效果:
我们会发现当让图片浮动之后,其后面的文字会围绕在图片的四周,与我们上述bug的样式有一定的区别,这也说明了float浮动是专门为图片环绕效果出现的,那为什么我们还会去用浮动进行布局呢?
其实也很容易想到,浮动属性用来布局是非常符合我们现实世界中“垒砖头砌墙”的认知的,反应在我们的代码实现上就是把元素一个一个定宽定高,通过浮动一个一个堆积起来,理论上一个float:left声明几乎就可以把整个页面结构都弄出来,而且内联元素的间隙问题/margin合并问题都没有了,这么一说是不是觉得float优点还挺多,哈哈,乍一看你float好像可以满足我们布局页面的需求,但是实际上我们在用float布局的时候,会出现很多现实问题。
举个例子,一旦某个列表的高度变高了,那么后面的列表就可能发生我们不愿看到的布局错位,抑或是日后我们需要增加某个元素的宽度,则也会牵一发而动全身,其他元素也必须跟着调整,否则样式必乱,也就是说float布局的容错性很糟糕,他缺少弹性。
二.float属性的影响
float属性的影响归根结底还是由于自身各种特性导致的,float有一些很有意思的特性,例如:破坏文档流,块状化并格式化上下文,没有任何margin合并等等。
1.什么是文档流?
float第一个特点就是破坏文档流,那么这个文档流是什么呢?
文档流实际上是指css世界中的一种基本的定位和布局机制,与我们现实生活中的水流是一样的,在现实生活中,如果我们让水注入一个容器中,水面一定是平的,如果向其放入木头,水位就会升高,而木头会顺序排列,映射到css的世界中,html元素按照文档正常排列(默认从左往右从上到下的顺序)如果图片文字依次排列超出行的区域则换行。
说白了文档流就是按照正常的文本流向。
那么说float会使元素脱离文档流,也就是说设置float的元素可以脱离原本的文本流向布局排列。
2.破坏文档流会有什么影响?
先来说下float是如何脱离文档流的,float浮动会使父元素的高度发生塌陷,使元素不占用普通流的位置,但这个塌陷并不是float的bug,而是他的标准,试想一下float的出现原本只是为了实现文字环绕效果,如果你是css的设计者。你会如何使用古老的css盒模型规则实现文字环绕效果?
css的设计者就想到了“破坏文档流”这一招。破坏文档流使父级高度塌陷只是让跟随的内容和浮动元素在一个水平线上,只要这一个条件还是实现不了文字环绕图片效果,要想真正实现还需要一个平时大家不太在意的特性,就是“行框盒子和浮动元素的不可重叠性”,也就是“行框盒子如果和浮动元素的垂直高度有重叠,则行框盒子在正常定位状态下只会跟随浮动元素,而不会发生重叠”(注;这里的“行框盒子”是指每行内联元素所在的那个盒子,而非外部的块状盒子)
实际上,由于浮动元素的塌陷,块状盒子是和图片完全重叠在一起的,举个例子:我们给图片旁边的文字添加一个包裹层div,再给其添加一个背景颜色,就会有以下效果:
3.什么是块级格式上下文?
float还有一个特别要提的特点就是会触发块级格式化上下文,也就是我们所说的BFC,说白了就是对于块状元素的的排版,垂直方向上是一个接一个的放置的,BFC也可以说是css世界的结界,通过一些特定的手段形成的封闭空间,里面的元素“出不来”(里面的元素对外面的元素没有任何的影响),外面的元素“进不去”(外面的元素对里面的元素没有任何的影响)。
如果一个元素具有BFC,内部子元素再怎么翻江倒海,翻云覆雨,都不会影响外部元素,所以BFC是不可能发生margin重叠的,因为margin重叠是会影响外面的元素的;浮动可以触发BFC,BFC也可以用来清除浮动的影响。BFC在计算垂直方向上大小的时候,会包含浮动元素。
4.什么时候会触发BFC?
常见的情况如下:
1)html根元素
2)float的值不为none
3)overflow的值为auto、scroll或hidden
4)display的值为table-cell、table-caption和inline-block中任何一个
5)position的值不为relative和static
三.如何清除浮动?
清除浮动的方法:
1.clear属性
css中专门用来处理floa属性带来的高度塌陷等问题的属性——clear,其语法如下:clear;none| left | rigth | both
none默认值,允许左右浮动
left: 左侧抗浮动
right: 右侧抗浮动
both: 两侧抗浮动
官方解释这个属性是:元素盒子的边不能和前面的浮动元素相邻.
大家有没有发现平时我们除了clear:both这个声明比较多以外,left和rigth两个属性值几乎无人问津,是因为left和right这两个值没有用吗?没错,确实没什么用,凡是clear:left或者是clear:right起作用的地方,一定可以使用clear:both替换。
现在我们就把最初的bug解决一下,清除一下浮动为父级带来的影响:
清除浮动后的效果:
注意:clear属性只有块级元素才有效的,而:after等伪元素默认都是内联水平,这就是借助伪元素清除浮动影响是需要设置display属性值的原因。因此我们还可以用以下方法清除浮动带给父级的高度塌陷的影响。
效果:
2.为父级设置overflow: hidden/auto/scroll
效果
为什么overflow:hidden可以解决浮动呢?
答案很简单其实就是因为overflow:hidden触发了BFC,BFC在垂直方向的高度会将浮动元素也计算进去,父元素不会忽略自己里面的浮动元素的高度,如果你的父元素的高度设置的auto的话,那么它的高度就会等于浮动元素的高度(假设这个BFC里面只有一个浮动元素)。
3.为父级设置float: left;
效果
4.为父级设置display:table-cell、table-caption和inline-block中任何一个
效果
5.为父级设置;
效果
更多精彩内容记得duyi4299联系哦!
原文地址:https://blog.51cto.com/13409950/2473224