我们都知道,块级元素是单独占一行的。有时候我们希望让多个块级元素排在一行显示,其中一个方法就是让元素浮动,也就是今天要说的float属性。
float属性包含3个属性值:
元素设置float属性,属性值为left或者right时,该元素会脱离原本的文本流,向包裹的父元素左/右浮动。
举个例子:
首先设置一个父元素,class=“father”,父元素中包含5个子元素,class=“son son标号”,如下所示:
<div class="father">
<div class="son son1">son1</div>
<div class="son son2">son2</div>
<div class="son son3">son3</div>
<div class="son son4">son4</div>
<div class="son son5">son5</div>
</div>
.father{
border: 1px dashed black
}
.son{
width: 50px;
height: 50px;
text-align: center;
line-height: 50px;
}
.son1{
background: red;
}
.son2{
background: yellow;
float: right
}
.son3{
background: lightgreen;
}
.son4{
background: lightblue;
}
.son5{
background: lightgray;
}
没有浮动的话,每个子div单独占一行,5个div就占5行,父级div没设宽和高,默认的宽为相对body的宽度,为100%;高度默认为0,5个子div将高度撑起,所以高度为5个子div的高:
为所有子元素加float:left,效果如下:
可以看到,5个子div脱离文档流,向左侧依次浮动,但是由于子元素脱离父元素,父元素本身又没有高度,所以父元素高度为0。这便是浮动元素引出的第一个问题:
父级元素无法撑开,影响与父元素同级的元素位置
现在,给son1~son4添加float属性值,son5不加float,可以看到效果如下:
son1~son4四个子元素脱离文档流,浮动在页面上方,但son5还在父元素中,还在页面内,因此会对同级子元素遮挡。浮动元素引出的第二个问题:
与元素同级的非浮动元素会紧随其后,并被浮动元素遮盖
如果给son2~son5添加float属性值,son1不加float,可以看到效果如下:
由于son1元素没有float属性,所以单独占一行,其余四个在下面一行左浮动。但是由于son2~son5脱离文本流,所以浮动在父元素外面。浮动元素引出的第三个问题:
如果一个元素浮动,则该元素之前的元素也要浮动,否则会影响页面显示结构,如串行等
清除浮动,说白了就是即使子元素脱离文本流,但还让父元素能包裹子元素。如下图所示:
解决办法
- 简单粗暴的方法,给父元素加一个高度,看起来好像父元素还包裹着子元素一样,但是实际上浮动的子元素还是脱离文档流的,这种方法不建议使用。
- 为父元素设置overflow:hidden,即可清除浮动。
.father{
border: 1px dashed black;
overflow: hidden;
}
我们都知道overflow: hidden是让超出元素内容的部分隐藏。但是在这里也有清除浮动的作用,具体原理大家自行百度吧,比较复杂,会用就行。
- 用clear:both样式属性清除元素浮动。
clear属性首先是浮动元素的一个属性,可以清除元素周围的浮动。在W3C School中关于clear的属性值有这样一个表述:
但上述描述其实并不准确,举个例子:
还是以上面5个div为例,首先对所有元素float设置为left,显示效果为左浮动,这个没问题:
对son2属性加一个clear:left或者clear:both,效果如下:
是不是看出点问题了。按理说clear:both应该是左右两侧都不允许出现浮动元素,但是son2当设置clear为both时,只有clear:left效果,即左边没有了浮动元素,但右边还有浮动元素。
这时我们把son3~son5的属性设置为float:right,son1 ~ son2属性还是float:left,son2设置clear:both, 再看一下效果:
好像clear:right属性还是没什么效果。
将所有元素都设置为clear:right,son2设置clear:both或者clear:right,效果如下:
这时候clear:right属性好使了,但是clear:left属性又不好使了。
那么clear:both什么时候才好使呢?
通过查阅相关资料,其实clear:both一般是一种头脑懒于思考,你也不用告诉我元素是float:left还是float:right,反正通通清除元素浮动,但实际上,任意浮动元素用clear:both和float:left元素用clear:left和float:right元素用clear:right属性是一个效果的。
- 用clear:both清除元素浮动的常用方法:
内墙法:在父元素内部,所有浮动元素最后面,添加一个div,属性为clear:both。
<!-- son 属性为float:left -->
<div class="father">
<div class="son son1">son1</div>
<div class="son son2">son2</div>
<div class="son son3">son3</div>
<div class="son son4">son4</div>
<div class="son son5">son5</div>
<div style="clear:both"></div>
</div>
为啥这个方法就好使呢?首先来说,这个div虽然没有高度,但是依然是一个块级元素,假装占有一个位置。因为其他5个都是浮动元素,所这个没有高度的div被5个浮动元素遮挡,并存在于父级元素中。当div设置clear:both属性时,说明它左边不能存在浮动元素,并处于son下面的一行。同时,这个div没有高度,又在父元素之中,所以父元素被撑开,清除浮动。
网上还有一种方法叫外墙法,我没弄出来,而且网上说这种方法不常用,所以感兴趣的小伙伴自行搜一搜吧。
- 对父元素添加after伪元素,设置属性content:"";display:block;clear:both
.clearfix:after{
content:'';
display:block;
clear: both
}
<div class="father clearfix">
<div class="son son1">son1</div>
<div class="son son2">son2</div>
<div class="son son3">son3</div>
<div class="son son4">son4</div>
<div class="son son5">son5</div>
</div>
极力推荐以上这种方式,因为clearfix已经应用各大CSS框架(如BootStrap等)中,并且成为行业的默认规范。