十分钟掌握面试热门问题--浮动,BFC
浮动\textcolor{469efc}{浮动}浮动
浮动,一个小小的知识点,但是大多数人都会忽视它,比如说初学css的小白们,现在把它拿出来,是因为它居然是很多面试官的必问题!
来吧!话不多说,直接进正题!
一、浮动的特性\textcolor{469efc}{一、浮动的特性}一、浮动的特性
1、文字环绕
现在来聊聊浮动的第一个特性吧,看下面的小例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.pic{
width: 200px;
height: 200px;
}
.pic img{
width: 100%;
}
</style>
<body>
<div class="pic">
<img src="image/QQ图片20230323100549.jpg">
</div>
<div class="text">
从语言的系属来看,我国56个民族使用的语言分别属于五大语系:汉藏语系、阿尔泰语系、南岛语系、南亚语系和印欧语系。
汉藏语系分为汉语和藏缅、苗瑶、壮侗三个语族。
属于藏缅语族的有藏、嘉戎、门巴、仓拉、珞巴、羌、普米、独龙、景颇、彝、傈僳、哈尼、拉祜、白、纳西、基诺、怒苏、阿侬、柔若、土家、载瓦、阿昌等语言;
属于苗瑶语族的有苗、布努、勉等语言;属于壮侗语族的有壮、布依、傣、侗、水、仫佬、毛南、拉珈、黎、仡佬等语言。
阿尔泰语系分为蒙古、突厥、满—通古斯三个语族。属于蒙古语族的有蒙古、达斡尔、东乡、东部裕固、土、保安等语言;
属于突厥语族的有维吾尔、哈萨克、柯尔克孜、乌孜别克、塔塔尔、撒拉、西部裕固、图佤等语言;
属于满—通古斯语族的有满、锡伯、赫哲、鄂温克、鄂伦春等语言。属于南岛语系的是高山族诸语言,还有回族的回辉话。
属于南亚语系孟高棉语族的有佤、德昂、布朗、克木等语言。属于印欧语系的是属斯拉夫语族的俄语和属伊朗语族的塔吉克语。
[2]有些语言的系属尚未取得统一意见,如朝鲜语、京语等。
</div>
</body>
</html>
这是页面效果:
当我们想要图片与文字处于同一行时,我们能想到很多种方法,比如用弹性布局,定位等等,现在有了浮动,一行代码就能完美呈现,那就是在pic容器中加入float:left;这个样式,于是,就有了这样的效果:
这就是浮动的第一个基本特性:实现文字环绕效果!
2、让块级元素同行显示,元素会脱离文档流,父容器的高度会塌陷
我们设置三个容器,小红,小绿,小蓝
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
div{
height: 100px;
width: 100px;
border: 1px solid #000;
}
.item1{
background-color: #fddcdc;
}
.item2{
background-color: #9ff1a8;
/*float: left;*/
}
.item3{
background-color: #469efc;
}
</style>
</head>
<body>
<div class="item1">one</div>
<div class="item2">two</div>
<div class="item3">three</div> <!-- div换行就会导致三个div之间有间隙 解决:父容器设置font-size:0; -->
</body>
</html>
页面如下:
我们现在知道可以用float:left;属性实现同行显示,那么我们就在小绿上加上这个属性吧!
欸,咋变成这样了?
原因是小绿设置了浮动属性,浮动的元素会脱离文档流,什么是文档流呢?举个例子,脱离文档流的容器好比逆子,那他爹(父容器)也不管他,那么布局也会向前推进,所以小蓝来到了小绿的位置,而小绿盖住了小蓝。
我们还会发现一个问题,没加浮动属性时三个容器的父容器body高度对比加了浮动属性后父容器body高度,塌陷了! 下面是效果对比图:


3、让行内元素可以设置宽高
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.box{
width: 100ww;
height: 200px;
background-color: #ebf5de;
}
span{
width: 100px;
height: 100px;
/*float: left;*/
background: #e7caca;
}
</style>
<body>
<div class="box">
<span>1</span><span>2</span><span>3</span>
</div>
</body>
</html>
我们知道,span是行内元素,无法设置宽高,但我们在span中加入float:left;属性后就有了相应的高度。下面是效果对比图:


4、浮动元素可以设置margin,但是不能设置margin:0 auto;
基于第三个特性的例子,我们来实现三个span在x轴居中的效果,如果我们用这个很简单的属性margin:0 auto;实现x轴居中:
span{
width: 100px;
height: 100px;
float: left;
background: #e7caca;
/* margin-left: 30px; */
margin: 0 auto;
}
运行之后我们发现这三个元素居然不会居中!
那我们就在span中删除float:left;这个属性,加上display:block;变成块级元素
span{
width: 100px;
height: 100px;
/* float: left; */
background: #e7caca;
/* margin-left: 30px; */
margin: 0 auto;
display: block;
}
就可以实现居中啦,这就得出一个结论:用margin:0 auto;实现x轴居中 在有float: left;这个属性的情况下无效
那么我们试试在有float: left;这个属性的情况下用margin的其他属性呢,比如margin-left: 30px;
span{
width: 100px;
height: 100px;
float: left;
background: #e7caca;
margin-left: 30px;
/* margin: 0 auto;
display: block; */
}
发现margin-left: 30px; 起效果了,所以浮动元素可以设置margin(除了margin:0 auto;)
二、清除浮动\textcolor{469efc}{二、清除浮动}二、清除浮动
But,虽然浮动很好用,但是他会造成一些不好的影响,比如说用浮动会导致父容器塌陷等等,所以,我们就需要清除浮动带来的负面效果。
1、直接设置父容器的高度
听起来很直接简单,但是会导致一个问题,用户在不同设备上(比如手机和ipad)看到的父容器高度是相同的,这就带来了不好的用户体验,所以一般不使用此方法。
2、增加子容器,在子容器身上做清除浮动||给下面受影响的容器添加clear:both;
1)在ul列表中加入一个div,给这个容器设置clear:left;属性来清除左浮动;
反之,若给ul列表中的li设置右浮动,则用clear:right;属性来清除; 当然,若既向左浮动又向右浮动,则用clear:both;属性来清除。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
ul li{
list-style: none;
width: 100px;
height: 100px;
margin: 10px;
background: #d28e8e;;
float: left;
}
.clear{
clear:left;
/* clear:both; */
/* clear:right; */
}
.content{
width: 200px;
height: 100px;
background-color: #a7e8da;
/* clear:both; */
}
</style>
<body>
<div class="box">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<div class="clear"></div>
</ul>
</div>
<div class="content"></div>
</body>
</html>
But,这种方式增加了一个不必要的空容器,所以也一般不采取此方法。
2)在下面受影响的容器content中添加clear:both;属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
ul li{
list-style: none;
width: 100px;
height: 100px;
margin: 10px;
background: #d28e8e;;
float: left;
}
.content{
width: 200px;
height: 100px;
background-color: #a7e8da;
clear:both;
}
</style>
<body>
<div class="box">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<div class="clear"></div>
</ul>
</div>
<div class="content"></div>
</body>
</html>
But,它并没有降低代码的耦合度,所以一般也不采用。
3、通过伪元素xx::after{content: '';clear: both;display: block;}
伪元素的方法就很好的弥补了上述方法的缺点,代替了空容器div 继续上面的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
ul li{
list-style: none;
width: 100px;
height: 100px;
margin: 10px;
background: #d28e8e;;
float: left;
}
ul::after{
content: '';
clear: both;
display: block;/*行内元素变块级 */
}
.content{
width: 200px;
height: 100px;
background-color: #a7e8da;
}
</style>
<body>
<div class="box">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<div class="clear"></div>
</ul>
</div>
<div class="content"></div>
</body>
</html>
在增加了伪元素后,来看看效果:
清除浮动成功!这种办法应该是目前最nice的方法了。
4、借助BFC容器的特点,抵消掉浮动的负面影响
好!问题来了,什么是BFC容器呢?
BFC全称Block formatting Context,是css渲染的一部分,主要决定盒子的布局和浮动相互影响的一个区域。
那怎么创建BFC容器呢?通过添加以下属性: 1)浮动(float:left/float:right) 2)overflow:auto/hidden/scroll/overlay 3)display:inline-block 4)网格布局(grid/inline-grid) 5)表格布局(table/table-cell/table-caption/inline-table) 6)弹性布局(flex/inline-flex) 7)定位(absolute/fixed)
继续上个例子,在ul中加入overflow: hidden;属性将其变为BFC容器:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
ul li{
list-style: none;
width: 100px;
height: 100px;
margin: 10px;
background: #d28e8e;;
float: left;
}
.content{
width: 200px;
height: 100px;
background-color: #a7e8da;
}
ul{
overflow: hidden;
/*overflow: auto; */
/* display: table-cell; */
/* float: left;*/
}
</style>
<body>
<div class="box">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<div class="clear"></div>
</ul>
</div>
<div class="content"></div>
</body>
</html>
清除浮动成功!
同时可以看到BFC容器计算高度时,会将浮动元素的高度也计算在内,也维护一个常规的文档流。
扩展一下\textcolor{469efc}{扩展一下}扩展一下 BFC还可以解决子容器和父容器margin重叠的问题
举个例子:
box是父容器,top是其子容器,我们要实现下图效果:
那么我们在box中加入margin-top: 100px; , 在top中加入margin-top: 50px;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
.box{
height: 500px;
background: #f9e0e0;/*粉色*/
margin-top: 100px; /*父容器与子容器margin重叠 */
/*overflow: hidden;*/
}
.top{
height: 200px;
background: #bee2fa;/*蓝色*/
margin-top: 50px;/*父容器与子容器margin重叠 */
}
.bottom{
height: 100px;
background: #c9f9d4;/*绿色*/
}
</style>
<body>
<div class="box">
<div class="top"></div>
<div class="bottom"></div>
</div>
</body>
</html>
发现蓝色容器top并没有距离父容器顶部50px距离,但我们在父容器box中加入overflow: hidden; 后就能达到效果啦!
那我们又会想,BFC能不能解决子容器之间(top与bottom容器)的margin重叠问题呢? 答案是:不能! 解决方法:我们知道,BFC容器包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素,所以我们在bottom容器外加上一个类名为bfc的div,给这个div加上overflow: hidden; ,这样就把这个div变成了bfc容器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
.box{
height: 500px;
background: #f9e0e0;/*粉色*/
margin-top: 100px; /*父容器与子容器margin重叠 */
overflow: hidden;
}
.top{
height: 200px;
background: #bee2fa;/*蓝色*/
margin-top: 50px;/*父容器与子容器margin重叠 */
margin-bottom: 50px;/*子容器之间margin重叠 */
}
.bottom{
height: 100px;
background: #c9f9d4;/*绿色*/
margin-top: 50px;/*子容器之间margin重叠 */
}
.bfc{
overflow: hidden;
}
</style>
<body>
<div class="box">
<div class="top"></div>
<div class="bfc">
<div class="bottom"></div>
</div>
</div>
</body>
</html>
下图是最终效果:
结语\textcolor{469efc}{结语}结语
看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~ 文章可能有一些错误,欢迎评论指出,也欢迎一起讨论。
转载自:https://juejin.cn/post/7215809449909682235