习惯性去谷歌翻译看了看float的解释: css
she relaxed, floating gently in the waterhtml
瞬间浮想联翩,一个女神,轻轻地漂浮在水中。开心的拍打着水花,哇靠。。。前端
不想了,人间不值得,步入正题吧,上面美妙的画面中,咱们能够看到,女神仍是挤占了水的空间,女神是浮动的。那么来,好了,编不下去了,直接开题吧。。。api
我以为不少人连float
是啥意识都不知道,要知道不少特性的原理是和其命名的单词或者字母有密切关联的,不是随便命名的。从名字中能够看到一些当初设计的初衷。浏览器
问本身三个问题:bash
第一 浮动会形成什么影响?
第二,如何解决这些由于浮动而形成的影响?
第三,bfc原理?
复制代码
其实我我的理解,浮动形成的最核心的问题就是破坏了文档流,那么问题来了,float
破坏了文档流,为何还要设计这个api
,我查了一些资料最后才知道,这是由于当初设计float
的目的是为了能实现文字可以环绕图片的排版功能,也就是咱们有时会纳闷的一点:设置浮动后,仍是会挤占容器中的文本内容。布局
好比看下面这段代码:spa
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>float实现浮动</title>
</head>
<style> .z1{ height: 200px; width: 200px; float: left; text-align: center; line-height: 200px; background: skyblue; } .fu { width: 400px; } </style>
<body>
<div class="fu clearfix">
<div class="z1">设置了float为left的图片</div>
<div class="z2">你看,我没有被浮动哥哥挡住哦,这是一段神奇旅行,一天我赶上了白雪公主</div>
</div>
</body>
</html>
复制代码
效果图以下:翻译
看到这,是否是有些理解了。从上图会发现,即便图片浮动了,脱离了正常文档流,也覆盖在没有浮动的元素上了,可是其并无将文本内容也覆盖掉,这也证明了float
这个api
在当初被设计出来的主要目的:实现文字环绕图片排版功能。设计
当想到这时,我忽然意识到,其余布局模式是什么样子,而后进行了实验。去掉容器z1
的float
属性,增长了position
属性,代码以下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>absolute实现浮动</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; position: absolute; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.8; } .fu { width: 400px; } </style>
<body>
<div class="fu clearfix">
<div class="z1">设置了positon为absolute的图片</div>
<div class="z2">你看,我被absolute哥哥挡住哦,这是一段神奇旅行,一天我赶上了白雪公主</div>
</div>
</body>
</html>
复制代码
效果图以下:
咱们能够看到,设置absolute
的容器,才是意义上的彻底脱离正常文档流。覆盖在当前位置上的全部容器和文本内容之上。对比思考一下,会发现这又证实了float
被设计出来的主要目的。若是能理解成这样,我以为对于不一样业务上该用什么方式清除float
,或者说该用什么来代替float
,将会有个很明确的方向。
其实你会发现,absolute
和float
都不会去覆盖掉在他们以前的正常文档流,这应该和浏览器渲染机制有关系,会从上到下依次渲染内容,渲染成功后,就不会由于后续元素浮动而使其被覆盖住(不考虑使用fix等强行覆盖的状况)。
简易代码以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮动</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; } .z5 { background: pink; } </style>
<body>
<div class="fu">
<div class="z2">没有设置任何浮动的容器,背景为黄色</div>
<div class="z3">没有设置任何浮动的容器,背景为红色</div>
<div class="z1">设置了浮动的元素,opacity为0.5</div>
<div class="z4">没有设置任何浮动的容器,背景为绿色</div>
<div class="z5">没有设置任何浮动的容器,背景为粉色</div>
</div>
</body>
</html>
复制代码
效果图以下:
从图中的标注和说明咱们能够清晰的知道,float
不会影响前面已经渲染好的文档,而会影响在其后面将要渲染的文档。那么问题来了,怎样才能消除由于z1
的浮动而对z4
,z5
形成的影响呢?
首先咱们要知道,z1
这个浮动形成了哪些影响,影响以下:
第一个影响:影响了
z4
,z5
的布局。
第二个影响:影响了父容器的高度,正常父元素的高度是自适应的,高度为其包含的内容总高度,而内部元素的浮动形成了父容器高度塌陷。
第三个影响:父容器高度塌陷了,将会影响和父元素同级的文档布局。
下面的代码能够完美的诠释这些影响:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮动</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; } .z5 { background: pink; } .z6 { color: #fff; background: black; } .z7 { color: #fff; background: blue; } .fu { /* overflow: hidden; */ } </style>
<body>
<div class="fu">
<div class="z2">没有设置任何浮动的容器, 背景为黄色</div>
<div class="z3">没有设置任何浮动的容器, 背景为红色</div>
<div class="z1">设置了浮动的元素, opacity为0.5</div>
<div class="z4">没有设置任何浮动的容器, 背景为绿色</div>
<div class="z5">没有设置任何浮动的容器, 背景为粉色</div>
</div>
<div class="z6">和父级元素同级的容器, 没有设置任何浮动, 背景为绿色</div>
<div class="z7">和父级元素同级的容器, 没有设置任何浮动, 背景为绿色</div>
</body>
</html>
复制代码
效果图以下:
要解决这三个影响,须要从两个方向思考:
第一个方向:解决父元素给其同级的元素形成的影响,我比喻成解决外部矛盾。
第二个方向:解决父级元素内部的浮动元素对其同级元素的影响,我比喻成解决内部矛盾。
俗话说的好,家丑不可外扬,那么来,如今就先解决外部矛盾,怎么解决呢,解决的思想,无非就是让父级元素的高度再也不塌陷,把浮动元素的高度算进去。记住一个关键点,这时候,内部矛盾仍是存在的。好比浮动元素和其后续的同级元素有高度重叠。
第一个是触发bfc
,为何呢,由于触发bfc
后,高度会包括浮动元素的高度。怎么触发呢,能够给父级元素设置overflow:auto;
对于其余的触发bfc
方式,我就不说了,我主要说一下原理。代码以下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮动</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; } .z5 { background: pink; } .z6 { color: #fff; background: black; } .z7 { color: #fff; background: blue; } .fu { overflow: hidden; } </style>
<body>
<div class="fu">
<div class="z2">没有设置任何浮动的容器, 背景为黄色</div>
<div class="z3">没有设置任何浮动的容器, 背景为红色</div>
<div class="z1">设置了浮动的元素, opacity为0.5</div>
<div class="z4">没有设置任何浮动的容器, 背景为绿色</div>
<div class="z5">没有设置任何浮动的容器, 背景为粉色</div>
</div>
<div class="z6">和父级元素同级的容器, 没有设置任何浮动, 背景为绿色</div>
<div class="z7">和父级元素同级的容器, 没有设置任何浮动, 背景为绿色</div>
</body>
</html>
复制代码
效果图以下:
给父元素增长伪元素:代码以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮动</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; /* clear: left */ } .z5 { background: pink; } .z6 { color: #fff; background: black; } .z7 { color: #fff; background: blue; } .fu { } .clearfix:after { display: block; overflow: hidden; content: '伪元素的内容哦'; clear: both; height: 0; background: slateblue; } </style>
<body>
<div class="fu clearfix">
<div class="z2">没有设置任何浮动的容器, 背景为黄色</div>
<div class="z3">没有设置任何浮动的容器, 背景为红色</div>
<div class="z1">设置了浮动的元素, opacity为0.5</div>
<div class="z4">没有设置任何浮动的容器, 背景为绿色</div>
<div class="z5">没有设置任何浮动的容器, 背景为粉色</div>
</div>
<div class="z6">和父级元素同级的容器, 没有设置任何浮动, 背景为绿色</div>
<div class="z7">和父级元素同级的容器, 没有设置任何浮动, 背景为绿色</div>
</body>
</html>
复制代码
不少人不清楚用伪元素清除浮动的原理是什么,为何给父元素加这个伪元素,能够清除父元素的浮动。这里我故意在伪元素的content
写了一些文本内容,同时加了背景色,有点像基佬色。。。
OK,先看总体效果图吧:
display:block
,继续看下一个截图。
height
要设置成0了。若是
content
不是空字符串,那么就会在页面中显示内容。但其实清除浮动时,
content
都会写成空的字符串,若是
content
里面只设置成
''
空的字符,那么
height
也能够不写,包括
overflow
也能够不写,写
height
和
overflow
都是为了代码的鲁棒性。不过有个很重要,
content
这个属性,必需要写,不写
content
,是无法清除浮动的。
最重要的知识点要来了,请看两个截图:
content
显示出来,会发现
伪元素清除浮动的核心原理实际上是在给父元素增长块级容器,同时对块级容器设置clear
属性,使其可以清除自身的浮动,从而正常按照块级容器排列方式那样排列在浮动元素的下面。同时,父元素的同级元素也会正常排列在伪元素造成的块级元素后面,而不受浮动影响。
下面是干掉clear
属性后的截图:
给父元素再加一个块级子容器,固然这个也就是父元素的最后一个块级子容器了。同时给这个块级子容器设置clear属性来清除其浮动,这样这个子容器就能排列在浮动元素的后面,同时也把父元素的高度撑起来了。那么父元素的同级元素也能正常排列了。因此这个子容器不能有高度和内容,否则会影响父元素的布局。
写到这,外部矛盾的解决方式和各自的原理已经说的很清楚了。那么内部矛盾怎么解决呢?
其实,解决内部矛盾的原理和解决外部矛盾的第二种方式的原理是同样的,经过给被浮动影响的第一个元素进行清除浮动,就可使后面的元素也不会受到浮动影响了。代码以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮动</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; clear:both; } .z5 { background: pink; } .z6 { color: #fff; background: black; } .z7 { color: #fff; background: blue; } </style>
<body>
<div class="fu">
<div class="z2">没有设置任何浮动的容器, 背景为黄色</div>
<div class="z3">没有设置任何浮动的容器, 背景为红色</div>
<div class="z1">设置了浮动的元素, opacity为0.5</div>
<div class="z4">没有设置任何浮动的容器, 背景为绿色</div>
<div class="z5">没有设置任何浮动的容器, 背景为粉色</div>
</div>
<div class="z6">和父级元素同级的容器, 没有设置任何浮动, 背景为绿色</div>
<div class="z7">和父级元素同级的容器, 没有设置任何浮动, 背景为绿色</div>
</body>
</html>
复制代码
效果图以下:
给内部元素设置clear:both;
清除浮动后,会直接解决内部矛盾和外部矛盾。可能会有人想,若是z4容器后面又有一个浮动元素呢,这里我不想再解释了,由于可递归得出原理都是同样的,可是吧,我仍是上个代码分析一下吧:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>清除float浮动</title>
</head>
<style> .z1{ height: 200px; width: 200px; box-sizing: border-box; float: left; text-align: center; background: skyblue; padding-top: 80px; opacity: 0.5; } .z2 { background: yellow } .z3 { background: red; } .z4 { background: green; clear:both; } .z5 { background: pink; /* clear:both */ } .z6 { color: #fff; background: black; } .z7 { color: #fff; background: blue; } .fu { overflow: auto; } </style>
<body>
<div class="fu">
<div class="z2">没有设置任何浮动的容器, 背景为黄色</div>
<div class="z3">没有设置任何浮动的容器, 背景为红色</div>
<div class="z1">设置了浮动的元素, opacity为0.5</div>
<div class="z4">没有设置任何浮动的容器, 背景为绿色</div>
<div class="z1">设置了浮动的元素, opacity为0.5</div>
<div class="z5">没有设置任何浮动的容器, 背景为粉色</div>
</div>
<div class="z6">和父级元素同级的容器, 没有设置任何浮动, 背景为绿色</div>
<div class="z7">和父级元素同级的容器, 没有设置任何浮动, 背景为绿色</div>
</body>
</html>
复制代码
效果图以下几张截图:
父元素没有清除浮动,外部矛盾,内部矛盾都存在
父元素使用bfc清除浮动,外部矛盾解决,内部矛盾还存在
经过给父元素中的浮动元素后面的第一个同级块级元素设置clear清除浮动,内部矛盾解决,外部矛盾也解决。
对于clear
还有left
和right
,这个就不说了,api
的事情,正常both
就能够了。写到此,差很少要结束了。最后再总结一下吧:
不一样业务中可能须要不一样的清除浮动的方式,不论选择哪种方式,都避不开外部矛盾和内部矛盾,你的业务须要保留内部矛盾,只解决外部矛盾,仍是外部矛盾和内部矛盾都解决。这些得须要根据业务的特色来决定。其次,是使用bfc仍是clear仍是伪元素,使用bfc的话使用哪一种方式去触发。这也是根据业务的特色来决定。
文末的可爱声明:若是转发或者引用,请贴上原连接,尊重一下熬夜完成的劳动成果😂。文章可能有一些错误,欢迎评论指出,也欢迎一块儿讨论。文章可能写的不够好,还请多多包涵。为了前端,我也是操碎了心,人生苦短,我学前端,多一点贡献,多一分开心~