面试官问问题的时候是惜字如金的,不要指望他能够让你具体说出哪哪方面,面试官问你很有可能就是直接说:聊聊浮动。来,下面是回答这类问题的标准套路,这份指南请你保管好来。
- 浮动是什么
- 浮动的作用、特征
- 浮动带来的负面影响如何消除
很多人可能回答的时候只会说出其概念,作用,这里其实面试官最想听到的是你会如何去消除浮动。
本文重点是带大家看看第三点,如何消除浮动。但是这里我还是会详细讲下浮动,小白就认真看,老白就顺便当复习了。
浮动
当然,在讲浮动之前我们还需要复习下css元素的分类
- 块级元素:默认占据一整行,可以设置宽高
- 行内块元素:可以同行显示,可以设置宽高
- 行内元素:可以同行显示,不可以设置宽高
其实这里还有一个伪元素可以进行补充,伪元素一般不会显示效果,这里留一个坑我们后面讲BFC的时候再填。
行内块元素有一个需要注意的点,就是行内块元素之间默认是会有间距的,这个间距我们可以通过写代码时元素之间不换行解决,但是这样的代码太不规范了,公司不会让你这样写,为了让代码更加优雅,我们可以在style里面定义一个全局,将font-size
参数改为0。其原理就是换行也算是字体,这里不会有人要问后面的字怎么办吧,后面的字我们可以后面再定义class覆盖掉。
浮动有以下几点特征:
- 浮动最初的作用就是为了实现文字环绕这一效果
- 脱离文档流
- 让块级元素同行显示
- 让行内可以元素设置宽高
- 可以使用
margin: 0;
,但是不能使用margin: 0 auto;
(坑)
消除浮动
我们所说的消除浮动并不是指消除浮动的效果,而是浮动有不好的影响,我们需要干掉它!
浮动会有什么不好的影响呢?
**浮动会将此时的元素飘起来,导致后面的div盒子会上移。**如何理解这段话?
浮动之后的父容器会进行坍塌,最后的高度为真正子容器的高度
例一
我们在body里面给出三个div盒子
ini
<div class="item1"></div>
<div class="item2"></div>
<div class="item3"></div>
然后在设置style样式
css
div{
width: 100px;
height: 100px;
}
.item1{
background-color: black;
float: left;
}
.item2{
background-color: blue;
}
.item3{
background-color: brown;
}
此时的画面如下显示
如果我们在item1下面添加一个向左浮动,那么将会如下显示
大家发现没有,item2消失了,其实这是因为item1浮动后脱离了文档流,文档流指的是从上到下,从左到右的布局。item1浮动后相当于飘了起来了,原来站位看到第一个位置是空的,就会自动往前进,我们最终看的视角是俯视图,所以才有了这样的效果。
这么看似乎不能说明浮动带来的消极缺点,但是我们已经知道了这个原理。好,我们现在再来看一个例子。
例二
我们给出一个无序列表,每个序号都去掉前面的符号后设定大小颜色使其成为方块最后再加入一个盒子,如下:
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
ul li{
/*使列表前无标记*/
list-style: none;
width: 200px;
height: 100px;
}
/*这里因为没有单独给每个列表标记,所用我们可以用这个方法,选中li后再指定第几个,切记不能写成 ul:nth-child(1) */
li:nth-child(1){
background: red;
}
li:nth-child(2){
background: yellow;
}
li:nth-child(3){
background: green;
}
.text{
width: 100px;
height: 200px;
background: blue;
}
</style>
</head>
<body>
<div class="container">
<ul class="clear">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div class="text">Hello World</div>
</div>
</body>
</html>
效果如图
很好理解,都是块级元素,每个占一行。
我们现在在ul li
的样式中添加向左浮动:
css
ul li{
list-style: none;
width: 200px;
height: 100px;
float: left;
}
效果如图
如何理解1,2,3在同一行呢?
整个ul
中所有的元素都浮动了,于是大家都来到了浮动这一层,这一层也需要排队,此时排队的方式刷新了,可以同行显示,这里参考浮动大标题下面的5特征之第3个特征。这个现象没有什么毛病,但是为什么这个文本class不会往下显示,而是被覆盖了一部分,其实这里就是跟例一一样了。
其实这里有个很有意思的点,不知道大家发现没有,我们这里的ul
的高度变0了。
如图
888 * 0 这里的高度居然为0。怎么解释呢,就是刚刚那句重点下面的一句话:浮动之后的父容器会进行坍塌,最后的高度为真正子容器的高度 ,我们这里的浮动是写在ul
里面的li
中的,ul
此时作为父容器的存在,一旦子元素浮动也就是脱离文档流之后,不再作为父容器的子容器,你可以理解为儿子成为一个"逆子"了,所以最后父容器支撑高度为0,没有一个儿子还在。同理,例子一里面div
的父容器是body
,所以body
的高度也为0。像是这里,我特别希望各位读者可以自己亲自来敲敲代码实践下,这就是浮动带来的一个负面影响。
而文本hello world这个盒子是和ul
这个盒子同级的,ul
高度为0,所以我们的文本盒子会被ul
覆盖掉一部分。
所以我们如何解决掉这个问题呢,也就是让hello world这个盒子可以正常下移
重点
- 给父容器设置高度
- 在最后一个浮动元素之后添加新的元素,这个元素给一个clear属性
- 父容器伪元素after用clear做清除浮动
- 在下方被浮动影响的容器上做清除浮动
- BFC
第一点:给父容器设置高度
这点很好理解,直接给父容器写死,例二中我们专门写一个ul
的高度既可
css
ul{
height: 100px;
}
但是这样写非常low,因为这种写法没有考虑到用户屏幕的大小,不建议采纳
第二点:在最后一个浮动元素之后添加新的元素,这个元素给一个clear属性
xml
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<!-- ul里面是可以放div的 甚至html的标签名都可以乱写,但是会挨打噢-->
<div class="clear"></div>
</ul>
然后在clear盒子里面写一个属性clear: both;
arduino
.clear{
clear: both;
}
这里给大家解释下clear: both;这个属性,clear是为浮动量身定制的属性,浮动可以理解为一个水流,最终都会走完,也就是走到</ul>
这个闭标签,流到这里的时候clear挡住了这个水流,因此ul
就浮动不起来了,因此没有影响ul
的文档流,这个方法一定要注意就是新增的这个盒子一定是在父容器闭标签前一个位置,或者这里说的最后一个浮动元素之后的位置。
这样写比第一点方法好点,但是代码不够优雅,因为公司的项目一般都很大,每次都这样写一个盒子去挡浮动,也不建议采纳
第三点:父容器伪元素after用clear做清除浮动
我们先给父容器ul
添加一个class 名为clear
css
<ul class="clear">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
后在样式里写一个伪元素,里面用clear: both;
css
.clear::after{
/* 伪元素本身不显示,需要content属性起作用,相当于触发器*/
content: '';
/*告诉浏览器,伪元素after之后要清除浮动*/
clear: both;
/*伪元素设为块级元素*/
display: block;
}
伪元素
收回开头说的元素分类,现在说到伪元素
伪元素其实不属于三大类元素之一,所以我们需要将这个伪元素设置成块级元素。现在再结合上面伪元素样式的代码注释看就可以更好理解了
这个方法还不错,在这个五个方法中用的频率排行老二,老大是最后今天的主角BFC
第四点:在下方被浮动影响的容器上做清除浮动
直接对受害者下刀子
css
.text{
width: 100px;
height: 200px;
background: blue;
clear: both;
}
这样也可以?
大家可能觉得方法很好啊,但是这个不符合我们人类的思维逻辑,谁的锅谁来背啊,怎么能改变受害者!不推荐!其实这样写可能会破坏布局,还是不推荐!
第五点:BFC
可算聊到今天的主角了😭,面试官最想让你回答消除浮动的其实就是BFC,另外我之前的文章有提到过BFC,但是今天我会细讲下BFC
BFC
BFC(Block Formatting Context) 表示"块级格式化上下文",它是CSS布局中的一个重要概念,用于控制块级元素在页面上的布局和定位
所以哪些属性可以创建BFC呢?
因为都是代码,所以我放在代码块里:
arduino
1. float: left || right(注意没有top和bottom)(会脱离文档流)
2. position: absolute(相对于父容器) || fixed(固定的,相对于整个窗口)(会脱离文档流)
3. display: inline-block || flex || inline-flex || table-cell....大部分以table开头的属性
4. overflow: hidden || overlay(超出覆盖) || auto || scroll
下面的解释都是拿例二来看
解释第一个属性float:
如果我们单独给ul
写个float
属性,那么整个ul
都浮动了,ul
相比之前又有高度了,但是整体浮动,依旧会脱离文档流,hello world还是会被覆盖一部分。这里解决的浮动问题就是之前的父容器高度问题。
解释第二个属性position:
这里就是一个定位的方法,绝对定位可以让ul
脱离文档流,和float 一样的效果,还有一个fixed的参数,用的少大家可以看下上面的注释了解下
这里顺便说下脱离文档流,脱离文档流基本上就是浮动和定位两个方法。
解释第三个属性display:
这个属性的参数就很多了,尤其是table开头的,这个是表格布局,用的很少,面试官也不会这么刁钻让你去说具体的名字,太多了,面试官估计自己也不记得。
这里display用得多的就是flex(弹性布局)和inline-block(转成行内块元素)
解释第四个属性overflow:
这个属性应该是BFC高频考点了,用得非常多,hidden是超出则隐藏,overlay是超出则覆盖,auto是超出显示滚动条,scroll是即使没有超出也有滚动条
这里需要说明的是,像overflow和display的其他属性这里没有说就不能清除浮动,记住上面这些就够了
单单从清除浮动这里看,我们其实也可以总结出BFC的两个特点
- BFC可以计算高度,BFC容器在计算高度时,会将浮动元素的高度也计算在内
- 解决块级元素重叠问题
其实BFC还有几大特点,后面碰到我们再继续聊,今天我们就聊到这里,很希望大家可以跟着我一起敲下代码,实践出真知!
如果觉得本文对你有帮助的话,可以给个免费的赞吗[doge] 还有可以给我的gitee链接codeSpace: 记录coding中的点点滴滴 (gitee.com)点一个免费的star吗[星星眼]