CSS神器之一——块级格式化上下文BFC

CSS神器之一——块级格式化上下文BFC

块级格式化上下文(Block Formatting Context),简称BFC。BFC是一块独立的渲染区域,它规定了在该区域中,常规流块盒的布局。

这是一个非常重要的知识点,无论是项目页面的布局,还是和同事之间的交流,也或者是面试前端工程师,这都是经常会碰到的。

在这里补充常规流块级盒模型的相关知识:

  • 在水平方向上,必须撑满包含块
  • 在包含块的垂直方向上依次摆放
  • 若外边距无缝相邻,则进行外边距合并
  • 注意:常规流盒模型的自动高度和摆放位置,会忽视浮动元素,浮动元素在这里不展开描述
1、BFC概述

前面我们讲到,BFC会创建一个独立的渲染区域。那么,这些区域是如何创建的?这个区域是由某一个HTML元素创建,在以下的三种情况会在其内部产生BFC:

  • 根元素,也就是说元素实际上也创建了BFC区域,覆盖率网页中的所有元素
  • 浮动和绝对定位,这两者都是脱离文档流的
  • overflow属性值部位visible的块级盒模型

接着,我们来看一张图,这张图里的元素有父子关系,我们来分析这些元素是由什么情况下产生的BFC。
在这里插入图片描述
看看大家猜对了吗?分析结果如下:
在这里插入图片描述
这个布局里,产生了四个BFC区域:

  • 根元素创建的BFC,包含A, B, E, F, G
  • 元素A创建的BFC,也就是B
  • 元素C创建的BFC,也就是D
  • 元素G创建的BFC,也就是H
2、BFC的使用规则
  • 不同的BFC区域,进行渲染的时候互不干扰
  • 创建BFC的元素,内部和外部的渲染互不影响。换句话说,BFC的产生隔绝了内部和外部的联系。下面详细讲解具体规则。
(1)创建BFC的元素,它的自动高度需要计算浮动元素

元素塌陷问题

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <style>
        .container {
            background: rgb(170, 158, 158);
        }

        .item {
            float: left;
            width: 200px;
            height: 200px;
            margin: 10px;
            background: rgb(118, 169, 235);
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
</body>

</html>

我们希望container能够自动撑开,有背景色,但是当我们在浏览器打开的时候却发现,背景并没有出来:
在这里插入图片描述
打开控制台,我们发现container的高度居然是0???这么骚???这其实就是著名的元素塌陷问题,常规流元素会自动忽视浮动元素,在我们的代码里,它认为盒子内部并没有其他元素,所以高度为0。
那么,我们应该怎么解决呢?非常简单,我们只需要让元素塌陷的div创建BFC就可以了,因为创建BFC的元素会自动计算浮动元素的高度。其中,采用overflow: hidden的副作用最小,关键代码如下:

.container {
   background: rgb(170, 158, 158);
   /* 前两种方式会改变布局 */
   /* position: absolute;
   float: left; */
   /* 副作用最小 */
   overflow: hidden;

}
.item {
   float: left;
   width: 200px;
   height: 200px;
   margin: 10px;
   background: rgb(118, 169, 235);
}

但是副作用最小的方法一定适用所有情况吗?显然不是,如果仅仅为了解决高度坍塌,建议直接清除浮动。因为在有些时候,我们可能需要解决溢出显示问题,那么overflow显然不是一个好办法。如下为清除浮动的代码:

.clearfix{
	
}

在学习BFC之前,我们会暴力地使用额外的子元素把盒子撑开,代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Document</title>
    <style>
        .container {
            background: rgb(170, 158, 158);
        }
        .clearfix::after{
            content: "";
            display: block;
            clear: both;
        }
        .item {
            float: left;
            width: 200px;
            height: 200px;
            margin: 10px;
            background: rgb(118, 169, 235);
        }
    </style>
</head>

<body>
    <div class="container clearfix">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
</body>

</html>
(2)创建BFC的元素,它的边框盒不会与浮动元素重叠

我们写了如下代码,到浏览器上看效果

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <style>
        .float{
            width: 200px;
            height: 200px;
            margin: 10px;
            background: rgb(197, 10, 10);
            float: left;
        }
        .container{
            height: 00px;
            background: rgb(7, 220, 248);
        }
    </style>
</head>
<body>
    <div class="float"></div>
    <div class="container"></div>
</body>
</html>

常规流完全无视浮动元素,效果如下:
在这里插入图片描述
一旦让container创建BFC,事情就变得不一样了。我们修改如下代码:

.container{
    height: 300px;
    background: rgb(7, 220, 248);
    overflow: hidden;
}

再回到页面上看,container避开了float元素:
在这里插入图片描述
这个时候我们修改container的margin-left属性,试图调整和左边固定宽度的红色矩形距离,发现不起作用,因为它参照的是窗口左边缘,而不是红色矩形。也就是当调整到数值大于本身到页面左边缘距离的时候,才开始有作用,如下所示:
在这里插入图片描述
这就说明了BFC会避开浮动元素,这样的特性对于我们制作两栏布局有很大帮助,尤其是一栏固定宽,另一栏自适应。

(3)创建BFC的元素,它的边框盒不会与浮动元素重叠

以下代码到页面上看,你会发现,两者上边框重合。

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <style>
        .container{
            height: 300px;
            margin-top: 80px;
            background: rgb(212, 74, 208);
        }
        .child{
            height: 100px;
            margin: 50px;
            background: rgb(20, 228, 100);
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="child"></div>
    </div>
</body>
</html>

无论你怎么调margin值,上边框都死死重合。
在这里插入图片描述
这个时候就要运用BFC来解决,我们对代码做出如下修改,让父元素创建BFC:

.container{
    height: 300px;
    margin-top: 80px;
    background: rgb(212, 74, 208);
    overflow: hidden;
}

再回到页面上看,两者上边框不重合:
在这里插入图片描述
子元素是container产生的BFC,而container是根元素产生的BFC,所以他们不是同一个上下文产生的BFC,这就是说上边框不重合的原因。

3、总结

BFC就是产生一个独立的渲染区域,不同上下文产生的BFC之间互不干扰。比如绝对定位会脱离常规文档流进行定位,其父元素不会自动计算它的高度,会选择忽视。这对于解决CSS的经典布局bug,或者是平时项目的布局都有很大帮助。
下一篇博客,我会介绍利用BFC还有其他的布局技巧来进行页面布局,比如三栏布局、两栏布局等等,敬请期待。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值