📝个人主页:爱吃炫迈
💌系列专栏:HTML+CSS
🧑💻座右铭:道阻且长,行则将至💗
文章目录
- 浮动的定义
- 浮动的工作原理
- 浮动的特性
- 为什么要清除浮动
- 清除浮动的方式
- 利用clear样式
- 父元素结束标签之前插入清除浮动的块级元素
- 利用伪元素(clearfix)
- BFC清除浮动
浮动的定义
非IE浏览器下,容器不设高度且子元素浮动时,容器高度不能被内容撑开。此时,内容会溢出到容器外面影响布局。这种现象被称为浮动(溢出)。
浮动的工作原理
- 浮动元素脱离文档流,不占据空间(引起“高度塌陷”现象)
- 浮动元素碰到包含它的边框或者其他浮动元素的边框停留
浮动元素可以左右移动,直到遇到另一个浮动元素或者遇到它外边缘的包含框。浮动框不属于文档流中的普通流,当元素浮动后,不会影响块级元素的布局,只会影响内联元素布局。此时文档流中的普通流就会表现得该浮动框不存在一样的布局模式。当包含框的高度小于浮动框的时候,此时就会出现“高度塌陷”
浮动的特性
- 脱离标准文档流
- 文本环绕
- 块级元素横排显示
- 内联元素设置宽高
- 浮动元素支持 margin,但是不支持 margin: auto
- 元素没有设置宽度时,宽度为内容撑开宽
为什么要清除浮动
🌰🌰举个栗子
<div class="topDiv">
<div class="floatDiv">float left</div>
<div class="textDiv">text</div>
</div>
<div class="bottomDiv">bottom</div>
.topDiv {
width: 500px;
border: 2px solid black;
}
.floatDiv {
width: 100px;
height: 100px;
border: 2px dotted red;
color: red;
margin: 4px;
float: left;
}
.bottomDiv {
width: 500px;
height: 100px;
margin: 5px 0;
border: 2px dotted black;
}
.textDiv {
color: blue;
border: 2px solid blue;
}
渲染效果如下
这肯定不是我们想要的渲染效果,它可能存在如下问题:
- 文字围绕浮动元素排版,但我们可能希望文字(
.textDiv
)排列在浮动元素下方,或者,我们并不希望.textDiv
两边有浮动元素存在。 - 浮动元素排版超出了其父级元素(
.topDiv
),父元素的高度出现了塌缩,若没有文字高度的支撑,不考虑边框,父级元素高度会塌缩成零。 - 浮动元素甚至影响到了其父元素的兄弟元素(
.bottomDiv
)排版。因为浮动元素脱离了文档流,.bottomDiv
在计算元素位置的时候会忽略其影响,紧接着上一个元素的位置继续排列。
✨需要解决的问题:
- 需要清除.textDiv周围的浮动
- 因为父元素的兄弟元素位置只受父元素位置的影响,就需要一种方法将父级元素的高度撑起来,将浮动元素包裹在其中,避免浮动元素影响父元素外部的元素排列。
清除浮动的方式
利用clear样式
利用
clear: both
来清除浮动,首先clear
就是清除的意思,both
代表左浮动和右浮动都清除掉。通俗一点来讲,就是说清除别人对我的影响。
关于clear
值 | 描述 |
---|---|
left | 在左侧不允许浮动元素 |
right | 在右侧不允许浮动元素 |
both | 在左右两侧不允许浮动元素 |
none | 默认值,允许浮动元素出现在两侧 |
inherit | 规定应从父元素继承clear属性的值 |
我们尝试对上面例子进行如下修改:
//省略基本样式
.textDiv {
color: blue;
border: 2px solid blue;
//区别在这
clear: left;
}
解释一下:
通过上面的样式,.textDiv
告诉浏览器,我的左边不允许有浮动的元素存在,请清除掉我左边的浮动元素。然而,因为浮动元素(.floatDiv
)位置已经确定,浏览器在计算.textDiv
的位置时,为满足其需求,将.textDiv
渲染在浮动元素下方,保证了.textDiv
左边没有浮动元素。同时可以看出,父元素的高度也被撑起来了,其兄弟元素的渲染也不再受到浮动的影响,这是因为.textDiv
仍然在文档流中,它必须在父元素的边界内,父元素只有增加其高度才能达到此目的。(clear
的值为both
也有相同的效果,通俗理解就是,哪边不允许有浮动元素,clear
就是对应方向的值,两边都不允许就是both
)
如果我们把HTML中的.floatDiv和.textDiv交换一下位置呢?
<div class="topDiv">
<div class="textDiv">text</div>
<div class="floatDiv">float left</div>
</div>
<div class="bottomDiv">bottom</div>
解释一下 :
.textDiv
的位置先确定了,于是浮动元素就紧接着.textDiv
下方渲染在父元素的左侧。然而,父元素的高度并没有被撑起来,没有将浮动影响“内化”,导致浮动影响到了接下来的元素排版。看来,为达到撑起父元素高度的目的,使用clear清除浮动的方法还是有适用范围的。我们需要更加通用和可靠的方法。
父元素结束标签之前插入清除浮动的块级元素
HTML结构如下,在有浮动的父级元素的末尾插入了一个没有内容的块级元素div
<div class="topDiv">
<div class="textDiv">text</div>
<div class="floatDiv">float left</div>
<div class="blankDiv"></div>
</div>
<div class="bottomDiv">bottom</div>
给HTML添加CSS样式:
// 省略基本样式
// 区别在这里
.blankDiv {
clear: both; // or left
}
原理和第一个例子里.textDiv应用clear清除浮动,撑起父级元素高度的原理完全一样。这里强调一点,即在父级元素末尾添加的元素必须是一个块级元素,否则无法撑起父级元素高度。
利用伪元素(clearfix)
HTML结构如下,为了惯例相符,在.topDiv的div上再添加一个clearfix类
<div class="topDiv clearfix">
<div class="textDiv">text</div>
<div class="floatDiv">float left</div>
</div>
<div class="bottomDiv">bottom</div>
给HTML添加CSS样式:
// 省略基本样式
.clearfix:after {
content: '.';
height: 0;
display: block;
clear: both;
}
解释一下:
该样式在clearfix
,即父级元素的最后,添加了一个:after
伪元素,通过清除伪元素的浮动,达到撑起父元素高度的目的。注意到该伪元素的display
值为block
,即,它是一个不可见的块级元素(有的地方使用table,因为table也是一个块级元素)。
你可能已经意识到,这也只不过是前一种清除浮动方法(添加空白div
)的另一种变形,其底层逻辑也是完全一样的。前面的三种方法,其本质上是一样的。
BFC清除浮动
BFC全称是块状格式化上下文(Block Formatting Context),那为什么我们可以通过BFC来清除浮动呢?
✨我们首先来看BFC的特征:
- BFC容器是一个隔离的容器,和其他元素互不干扰;所以我们可以用触发两个元素的BFC来解决垂直边距折叠问题。
- BFC可以包含浮动;通常用来解决浮动父元素高度坍塌的问题。
- BFC能够清除浮动主要就是因为其“包含浮动“这条特性。那我们怎么才能触发BFC呢?
✨我们可以通过添加如下属性来触发BFC:
- 根元素,即
HTML
标签 - float 设为
left
、right
- overflow 设为
hidden
、auto
、scroll
- display 设为
table-cell
、table-caption
、inline-block
、flex
、inline-flex
- position 设为
absolute
、fixed
因此我们可以通过给父元素添加 overflow: auto 来实现BFC清除浮动:
HTML结构:
<div class="topDiv">
<div class="floatDiv">float left</div>
<div class="textDiv">text</div>
</div>
<div class="bottomDiv">bottom</div>
给HTML添加CSS样式:
//省略基本样式
.topDiv {
width: 500px;
border: 2px solid black;
//区别在这
overflow: auto;
}