likes
comments
collection
share

十分钟掌握面试热门问题--浮动,BFC

作者站长头像
站长
· 阅读数 13

浮动\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>

这是页面效果:

十分钟掌握面试热门问题--浮动,BFC

当我们想要图片与文字处于同一行时,我们能想到很多种方法,比如用弹性布局,定位等等,现在有了浮动,一行代码就能完美呈现,那就是在pic容器中加入float:left;这个样式,于是,就有了这样的效果:

十分钟掌握面试热门问题--浮动,BFC 这就是浮动的第一个基本特性:实现文字环绕效果

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>

页面如下: 十分钟掌握面试热门问题--浮动,BFC 我们现在知道可以用float:left;属性实现同行显示,那么我们就在小绿上加上这个属性吧!

十分钟掌握面试热门问题--浮动,BFC 欸,咋变成这样了? 原因是小绿设置了浮动属性,浮动的元素会脱离文档流,什么是文档流呢?举个例子,脱离文档流的容器好比逆子,那他爹(父容器)也不管他,那么布局也会向前推进,所以小蓝来到了小绿的位置,而小绿盖住了小蓝。

我们还会发现一个问题,没加浮动属性时三个容器的父容器body高度对比加了浮动属性后父容器body高度,塌陷了! 下面是效果对比图:

十分钟掌握面试热门问题--浮动,BFC 十分钟掌握面试热门问题--浮动,BFC

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;属性后就有了相应的高度。下面是效果对比图:

十分钟掌握面试热门问题--浮动,BFC 十分钟掌握面试热门问题--浮动,BFC

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;这个属性的情况下无效 十分钟掌握面试热门问题--浮动,BFC

那么我们试试在有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;) 十分钟掌握面试热门问题--浮动,BFC


二、清除浮动\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>

十分钟掌握面试热门问题--浮动,BFC 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>

在增加了伪元素后,来看看效果:

十分钟掌握面试热门问题--浮动,BFC 清除浮动成功!这种办法应该是目前最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 清除浮动成功! 同时可以看到BFC容器计算高度时,会将浮动元素的高度也计算在内,也维护一个常规的文档流。


扩展一下\textcolor{469efc}{扩展一下}扩展一下 BFC还可以解决子容器和父容器margin重叠的问题

举个例子:

box是父容器,top是其子容器,我们要实现下图效果: 十分钟掌握面试热门问题--浮动,BFC 那么我们在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>

十分钟掌握面试热门问题--浮动,BFC 发现蓝色容器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>

下图是最终效果:

十分钟掌握面试热门问题--浮动,BFC

结语\textcolor{469efc}{结语}结语

看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~ 文章可能有一些错误,欢迎评论指出,也欢迎一起讨论。