个人主页:爱吃炫迈
系列专栏:HTML+CSS
座右铭:道阻且长,行则将至
非IE浏览器下,容器不设高度且子元素浮动时,容器高度不能被内容撑开。此时,内容会溢出到容器外面影响布局。这种现象被称为浮动(溢出)。
浮动元素可以左右移动,直到遇到另一个浮动元素或者遇到它外边缘的包含框。浮动框不属于文档流中的普通流,当元素浮动后,不会影响块级元素的布局,只会影响内联元素布局。此时文档流中的普通流就会表现得该浮动框不存在一样的布局模式。当包含框的高度小于浮动框的时候,此时就会出现“高度塌陷”
举个栗子
<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
在计算元素位置的时候会忽略其影响,紧接着上一个元素的位置继续排列。✨需要解决的问题:
利用
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清除浮动,撑起父级元素高度的原理完全一样。这里强调一点,即在父级元素末尾添加的元素必须是一个块级元素,否则无法撑起父级元素高度。
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全称是块状格式化上下文(Block Formatting Context),那为什么我们可以通过BFC来清除浮动呢?
✨我们首先来看BFC的特征:
✨我们可以通过添加如下属性来触发BFC:
HTML
标签left
、 right
hidden
、 auto
、 scroll
table-cell
、 table-caption
、 inline-block
、 flex
、inline-flex
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;
}