文档流
在说浮动之前,先介绍一下文档流机制。
网页是一个多层的结构,通过CSS可以分别为每一层来设置样式。作为用户只能看到最顶上一层。这些层中,最底下的一层为文档流。文档流是网页的基础,我们所创建的元素默认都是在文档流中进行排列。
所以可以说网页中的元素主要有两个状态:
- 在文档流中。
- 脱离文档流。
block元素在文档流中的特点:
- 默认宽度是继承父元素的宽度。
- 默认高度是被内容(子元素)撑开。
- 可以自定义宽高。
- 在页面中独占一行,本质上是元素的内外边距、边框,width属性值的和要与父元素的宽度相等。
.box1 {
width: 200px;
height: 200px;
background-color: #bfa;
}
.box2 {
width: 300px;
height: 300px;
background-color: orange;
}
以上代码box1的宽高只有200px,但是因为盒子模型的水平布局公式,所以box1默认添加了margin-right属性。所以box2无法位于box1的右边,而是排列在下面一行,这就是block元素独占一行的原理。
inline元素在文档流中的特点
- 从左往右排列,直到一行之中无法容纳当前元素时会换到第二行继续排列。
- 无法定义宽高,宽高是由内容(子元素)撑开的。
- 在页面中不会独占一行。
浮动
什么是浮动
浮动是通过设置float属性使元素脱离文档流,并且向其父元素的左侧或右侧移动。
元素脱离文档流的特点:
- 盒子水平布局的等式不再需要强制相等,意味着块元素不再独占一行。
- 块元素的默认宽度是被内容(子元素)撑开,不再是继承父元素的宽度。
- 行内元素会具备块元素的特性,可以定义宽高。
另外浮动元素还具有以下特性:
- 浮动元素在水平方向/垂直方向都不会超过它前面的浮动元素。
- 如果浮动元素的上面是一个没有设置浮动的块级元素,则浮动元素无法上移。
- 除了纯文本之外,行内元素/行内块元素/浮动元素/溢出隐藏/都可以识别浮动元素的位置。
- 块元素无法识别浮动元素,所以如果块元素在浮动元素下面,会直接覆盖其位置。
浮动最初是解决图片嵌入文本并自适应对齐的问题,因为纯文本是可以识别浮动元素的位置的,意味着文字不会盖住浮动元素,所以可以做出文字环绕的效果,现在常用于布局。
浮动引起的问题
子元素浮动以后完全脱离文档流,将会无法撑起父元素的高度,导致父元素高度塌陷。
比如以下父级元素box1是块级元素,子元素box2和box3是浮动元素,无法撑开box1的高度。
.box1 {
border: 5px solid red;
background-color: aquamarine;
}
.box2 {
float: left;
width: 200px;
height: 200px;
background-color: orange;
}
.box3 {
float: left;
width: 200px;
height: 200px;
background-color: pink;
}
父元素高度塌陷还会引起父元素的兄弟元素排版问题,导致页面布局混乱。比如以下代码中bottom-div是块级元素,无法识别浮动元素,但其中的纯文本可以识别浮动元素。
<div class="top-div">
<div class="float-div">left</div>
<div class="text-div">As much mud in the streets as if the waters had but newly retired from the face of the earth.</div>
</div>
<div class="bottom-div">As much mud in the streets as if the waters had but newly retired from the face of the earth,
and it would not be wonderful to meet a Megalosaurus, forty feet long or so, waddling like an elephantine lizard up Holborn Hill.
</div>
<style type="text/css">
.top-div {
width: 500px;
border: 2px solid black;
}
.float-div {
float: left;
width: 120px;
height: 120px;
border: 2px dotted red;
color: red;
margin: 10px;
}
.text-div {
color: blue;
border: 2px solid blue;
}
.bottom-div {
width: 500px;
height: 100px;
margin: 5px 0;
border: 2px dotted orange;
}
</style>
清除浮动影响的方式
第一种方式是通过给目标元素添加clear属性,清除周围浮动元素对它的影响。原理是浏览器会自动为目标元素添加一个上外边距margin-top,使其位置不受其它浮动元素的影响。
clear属性的值可以是left(清除左侧浮动元素对当前元素的影响)、right(清除右侧浮动元素对当前元素的影响,both(清除两侧影响最大的那一侧)。clear的使用方式有以下几种:
- 直接给目标元素添加
clear属性(此处清除了文字左侧的浮动影响),所以text-div元素跑到了float-left元素下边,又因为自动添加了一个margin-top属性,所以撑起了父元素的高度。
.top-div .text-div {
clear: left;
color: blue;
border: 2px solid blue;
}
- 在父元素
top-div结束标签之前插入一个块级元素并且设置clear属性。
.top-div .blank-div {
clear: both;
}
- 在父元素中添加伪元素,注意
伪元素是行内元素,即使自动添加了margin-top属性也无法撑开父元素,所以用于清除浮动时需要转换为块级元素。
.top-div::after {
content: "";
display: block;
// 必须是块级元素
clear: both;
}
clear的终极使用方式是给目标元素添加一个clearfix类,再给其添加伪元素并且设置clear属性。值得注意的是伪元素还可以通过设置dispaly: table;解决元素外边距合并的问题,所以综上所述常用代码如下:
.clearfix::before,
.clearfix::after {
content: "";
display: table;
clear: both;
}
第二种方式是通过BFC特性清除浮动影响,比如给元素添加overflow属性可以使元素具备BFC特性,可识别浮动的子元素,所以可以解决高度塌陷问题,之后会解释什么是BFC。
- 注意
overflow的值不能为visible或clip。
.top-div {
width: 500px;
border: 2px solid black;
overflow: hidden;
}
BFC
什么是BFC
Block Formatting Context 块级格式化环境,是CSS中的一个隐式属性。
元素开启BFC后会变成一个独立的布局区域,并且具有以下特性:
- 不会被浮动元素覆盖。
- 子元素和父元素的外边距不会重叠。
- 可以包含浮动的子元素,不会导致高度塌陷。
如何让元素开启BFC特性
开启BFC的方式有很多种,但是所有开启BFC的方式有会有一些副作用,这里列出常用的一些方式。
body本身就具备BFC特性- 元素设置
float属性。(不推荐) - 通过
display属性将元素设为inline-block元素。(不推荐) - 元素设置
overflow属性且值不为visible和clip。 - 元素设置
position属性,值为absolute或fixed。