浮动的简介
规定元素向左或向右移动直到碰到包含块的边缘或浮动元素为止,浮动元素会脱离文档流并漂浮于文档流上方,其它常规流元素会当其不存在而填补它的空间,并且文字等行内元素会环绕在浮动元素的周围。
文档流
也叫常规流、普通流、标准流、正常流,是浏览器默认的排列元素的方式,按照源码的书写顺序依次将行内元素从左到右水平排列,块级元素从上到下垂直排列。
例子:
.a{
border: 1px solid #000;
}
.b{
border: 1px solid yellow;
}
.c{
margin-top: 20px;
height: 50px;
background-color: red;
}
.d{
height: 50px;
background: pink;
}
<span class="a">行内元素a</span>
<span class="b">行内元素b</span>
<div class="c">块级元素c</div>
<div class="d">块级元素d</div>
可以看到元素是按照源码顺序依次排列的。
float属性
用于将元素设置为浮动元素,并且可以让元素向左或右浮动。
属性值:
none:默认值,不浮动。
left:向左浮动。
right:向右浮动。
浮动元素的尺寸
块级元素:
- 不在独占页面一行
- 块元素的宽高自适应内容,也叫包裹性
- 不会上下外边距合并,因为不在按照块级格式化上下文来布局
- 不参与水平计算规则,margin为auto时为0
行内元素:
- 一般的行内元素脱离文档流后浏览器会强制变成块级元素,强制display = block,因此盒模型的水平和垂直方向上的属性它都可以设置。
脱离文档流的元素
我们上面提到浮动元素会脱离文档流,就是不在按照常规流的方式排列布局,按照其他的方式排列,比如:可以不按顺序排列,后面的元素可以排在前面元素的前面,从文档流中删除,不在占据文档流位置,两者重叠都是可以的。
脱离文档流的元素:
浮动、定位
这里只讨论浮动的排列方式,设置浮动元素后在元素从文档流中移出,不在占据文档流位置,浮于文档流上方,由于脱离文档流,其他文档流元素会忽视它,但是带有内容的元素、文本如行内元素、行内块、文字等都会为它让出位置,并且环绕在它的周围。
例子:默认情况下
块级元素是按照常规流的方式,按源码的书写顺序将块级元素从上到下垂直排列。
当我们给块级元素d加了浮动以后
我们看到d元素浮动了,不在按照常规流依次的摆放方式,它浮在文档的上方并覆盖元素e。因为e是文档流元素,而d浮动不在占据文档流位置了,于是e填补d原先的空间并和c组成新的文档流。
例子2:
内容文本会围绕在浮动的周围。
例子3:浮动元素会强制转换成块级元素
我们可以看到span元素的display为block了
浮动的特点
-
浮动元素可以向包含块的左侧或右侧移动,浮动元素不能超出包含块,最远只能到达包含块的左或右内边界。
-
如果左(右)浮动元素的前面是左(右)浮动元素则后置的左(右)浮动元素的边缘会紧跟着前面的浮动元素的边缘,并且浮动元素的顶端和浮动元素的顶端对齐,也就是浮动元素不会和浮动元素重叠,该规则可以使元素横向排列。
-
如果浮动元素的前面的元素是文档流块级元素,则浮动元素不会超过块级元素,浮动的顶部和块级元素的底部对齐。
-
如果块级元素的前面是一个浮动元素则会忽视浮动元素,因为浮动元素脱离文档流。
-
行内元素会避开浮动元素并环绕在浮动元素的周围,如果浮动元素的前面是行内元素则根据文字环绕的规则,浮动元素会优先排列,而行内元素会为其让出位置并环绕在浮动元素的周围。
注:如果文字没有在行盒中,浏览器会自动生成一个匿名行盒包裹文字
可以看到根据文字环绕的规则,行内元素会为其让出位置,于是浮动元素会先排列然后行内元素会环绕在该元素的周围。
- 如果包含块的宽度不够容纳浮动元素,则浮动元素会换行,直到具备足够的空间能容纳盒子,然后在向左或向右浮动直到碰到包含块的边缘或浮动元素的边缘为止。
注:如果浮动元素的高度不同,那么当它们向下移动时可能被其它浮动元素卡住。
- 浮动元素的顶端不得高于前面浮动元素的顶端或包含块的顶端,因为浮动元素总是跟着前面的浮动元素排列,特殊情况负margin除外。
清除浮动
clear属性:官方的解释是元素的框不与较早的某一侧浮动框排列
地址:https://www.w3.org/TR/CSS22/visuren.html#flow-control
属性值:
left:元素框不与较早的左侧浮动元素排列,要求元素的顶端低于左侧浮动元素底部边缘
right:元素框不与较早的右侧浮动元素排列,要求元素的顶端低于右侧浮动元素底部边缘
both,元素框不与较早的两侧浮动元素排列,要求元素的顶端低于两侧浮动元素底部边缘
官方:
作用: 清除浮动所带来得影响,比如浮动元素会覆盖其它元素,包含块的高度会塌陷,又或者你不希望后面的浮动元素跟着前面的浮动元素的后面。
我们从字面意思可以知道:
- clear清除浮动只能影响加了这个属性的元素本身,不能影响其他元素,并且只能清除前面(较早)的浮动元素。
- 清除浮动并不是真正清除,浮动元素还是会继续浮动,只是添加了clear的元素会显示在浮动元素的下方而已,因为你不希望该元素被浮动覆盖了,这样就可以达到元素不被浮动所覆盖。
注意: 行内元素使用clear无效,因为根据浮动的规则,行内元素会避开浮动元素,并且围绕在浮动元素的周围,因此使用clear无效。
例子1:
左浮动元素在文档流元素的前面所以必须使用clear:left,文档流元素不与前面的左侧浮动元素排列
<div style="width: 100px;height: 100px;background: yellow;float: left;">浮动元素</div>
<div style="width: 200px; height:200px; background: red; clear: left;">文档流元素</div>
例子2:
清除浮动只能影响加了clear属性的元素本身不能影响其他元素,在根据规则只能清除前面的浮动元素不能清除后面的浮动元素,因为clear的作用就是清除浮动所带来的影响,因为一般都是前面的浮动元素会影响(覆盖)后面的元素,因此后面的元素并不会影响前面的元素,因此你在前面的元素添加clear来清除后面的浮动元素是没用的。
<div style="width: 200px; height:200px; background: red; clear: left;">文档流元素</div>
<div style="width: 100px;height: 100px;background: yellow;float: left;">浮动元素</div>
清除无效,并不能让文档流元素排在浮动元素的后面。
例子3:
我不希望后面的浮动元素跟着前面浮动元素一起浮动,可以使用clear可以使后面的浮动元素显示在前面浮动元素下方。
<div style="width: 100px;height: 100px;background: yellow; float: left;">浮动元素</div>
<div style="width: 200px; height:200px; background: red; float:left clear: left;">文档流元素</div>
红色元素: 我不想跟你在一起,不想跟你做邻居,于是使用clear,使自身显示在红色元素的下方。
清除浮动的原理:
在css1和css2中,它会增加元素的上外边距,使元素落在浮动元素的下面,但这样做会忽视为清除元素顶端设置的外边距宽度。在css2.1中引入了清除区域,清除区域是在元素上外边距上增加额外的间距。之所以会向下移动是这个清除区域造成的
高度塌陷
是指文档流元素的自动高度,在计算时,不会考虑浮动元素,因为浮动元素脱离文档流,不占据文档空间,而父元素会忽视浮动元素。
解决办法:
- 创建BFC的元素自动计算子浮动元素的高度,因为创建BFC的元素它的内部和外部的渲染不能互相影响,如果父元素高度塌陷,使得浮动元素跑到外面了就影响了外面的元素,所以它会计算浮动元素的高度。
.a{
border:4px solid red;
overflow: hidden;
}
.b{
width: 100px;
height: 100px;
background: #000;
float: left;
}
<div class="a">
<div class="b"></div>
</div>
元素a的外面是元素html创建的bfc,而a元素的里面则是由a创建的BFC,因此a元素内和a元素外的渲染不能互相干扰,所以元素a会强制计算里面浮动元素的高度。
- 使用clear+after为元素的方法,根据clear的原理,添加了clear的元素将显示在浮动元素的下方,可以在最后面添加一个伪元素使得伪元素高度为0并且会落在浮动元素的下方,这样伪元素就会强制把父元素撑高到浮动元素那么高。
.clearfix::after{
display: block;
content: '';
clear: both;
}
<div class="a clearfix">
<div class="b"></div>
</div>
大家可以看到,after元素是在b元素之后因此可以使用clear元素,清除较早的浮动元素,并且after元素根据clear的规则会显示在浮动b元素的下方,因此父元素被after元素强制撑高到那么高。
- 给包含块设置高度。