浅谈BFC

141 阅读4分钟

BFC总结

前言

每次在看面试题的时候都能看到BFC这个概念。但都只是死记硬背一下然后就过去了。感觉还是要理解其概念并结合应用才能加深印象。今天就着重了解后做了一下总结。

BFC概念

块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。通俗一点来讲BFC元素内部元素是独立的存在并不会影响到外部元素。

触发BFC

只要满足下列任意一条即可触发BFC特性:

  • 根元素(<html> )
  • 浮动元素(元素的 float 不是 none)
  • 绝对定位元素(元素的 position 为 absolute 或 fixed)
  • 行内块元素(元素的 display 为 inline-block)
  • overflow 值不为 visible 的块元素

BFC应用

1. 使用BFC来防止margin叠加问题。在同一个BFC内时margin会重叠抵消后取其中最大值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <style>
    
        .first,.second{
                width: 100px;
                height: 100px;
                margin: 100px;
                background: rgb(5, 241, 163);
        }
        .second{
            margin-top:150px;
        }
    </style>
</head>
<body>
        <div class="first"></div>
        <div class="second"></div>
</body>
</html>

从效果上结果并不是我们想要的100px+150px=250px,而是150px。可以得出结论两个div都处于同一个BFC容器下时margin会重叠并取最大值为了解决这个问题我们可以将其放在不同的容器中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <style>
        
        .container{
            overflow: hidden;
        }
        .first,.second{
                width: 100px;
                height: 100px;
                margin: 100px;
                background: rgb(5, 241, 163);
        }
        .second{
            margin-top:150px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="first"></div>
    </div>
    <div class="container">
        <div class="second"></div>
    </div>
</body>
</html>

2. BFC 可以包含浮动的元素(清除浮动)

有时候我们会碰到这种情况,一个容器里包含浮动元素,而这个元素并没有高度,它包含的浮动元素将会脱离页面的常规流。我们通常会选择清除浮动。但我们同样可以通过定义一个BFC来达到这个目的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <style>
        
        .container{
            border: 1px solid #333;
        }
        .first{
                width: 100px;
                height: 100px;
                float:left; /* 里面包含浮动元素 */
                background: rgb(5, 241, 163);
        }
      
    </style>
</head>
<body>
    <div class="container">
        <div class="first"></div>
    </div>
    
</body>
</html>

在上面这个例子中因浮动的子元素而导致父元素将获取不到任何高度。为了解决这个问题,我们通过添加overflow: hidden,在容器中创建一个新的BFC

经修改

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <style>
        
        .container{
            overflow: hidden;  /*修改*/
            border: 1px solid #333;
        }
        .first{
                width: 100px;
                height: 100px;
                float:left;
                background: rgb(5, 241, 163);
        }
      
    </style>
</head>
<body>
    <div class="container">
        <div class="first"></div>
    </div>
    
</body>
</html>

现在,这个容器将包含浮动的子元素,它的高度将扩展到可以包含它的子元素,在这个BFC,这些元素将会回到页面的常规文档流。 结果如下

3. 自适应多列布局

如果我们想创建一个多列布局布满整个容器的宽度。但有的时候最后一列总会被无情的挤下去。这是因为浏览器的计算方式导致多列的总宽度会超过容器的宽度。

例子:

BFC创建前

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

<head>
    <meta charset="UTF-8">
    <style>
        .container {
            width: 500px;
        }

        .left {
            float: left;
            width: 100px;
            height: 100px;
            background: rgb(5, 241, 163);
        }

        .right {
            height: 300px;
            background: rgb(238, 240, 152);
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>

</body>

</html>

因此我们可以在最后一列建立一个新的BFC,它将会自动填充前一列并占据剩余空间就不会掉下去了。

例子: BFC创建后

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

<head>
    <meta charset="UTF-8">
    <style>
        .container {
            width: 350px;
        }

        .left {
            float: left;
            width: 100px;
            height: 100px;
            background: rgb(5, 241, 163);
        }

        .right {
            height: 300px;
            background: #333;
            overflow: hidden; /*修改*/

        }
    </style>
</head>

<body>
    <div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>

</body>

</html>

写在最后

  • 以上文章仅是个人拙见及自我总结,虚心接受指正。