什么是BFC并如何运用它

前言

最近忙于小程序的开发,鸽了两天没有更文,今天前来补上。老规矩在更此文之前,还是先简单过了一下之前的高赞文章,这个作为前端面试中常问的一个点,我们要清楚它并知道该如何应用它。

先别急于去了解什么是BFC,先来说说实际工作中的场景:
场景一: 可能你会维护别人写的项目对吧,在改他的bug的时候你得分析造成这些bug的原因,很可能当时他在写这些代码的时候只是为了实现而实现,东拼西凑去把效果实现了,造成的一些问题也不知道从根本上去解决,会导致代码越来越难维护,所以你要清楚怎么改,知道这么写可以带来什么效果。
场景二: 你负责第一版代码的开发,你在组织你的代码的时候,该如何以一种清爽的风格、语义化清晰的方式去进行开发,这也是我更此文的重要原因。我们知道实现一个效果有N种方法,但是是我希望你通过阅读此文可以为你以后得开发带来一定的影响,那就是此文带来的意义。

BFC

什么是BFC

在看概念之前,你首先得知道它是属于css2的范畴,虽然现在普遍都在用css3的弹性盒来进行页面的布局,但是也有很多项目多人开发迭代,会杂糅各种各样的写法。

首先你得清楚BFC概念:

A block formatting context (BFC) is a part of a visual CSS rendering of a web page. It's the region in which the layout of block boxes occurs and in which floats interact with other elements.

概念说的很清楚对吧,BFC是网页渲染可视CSS渲染的一部分。知道了BFC的概念,那么咱们继续走着,看看如何创建一个BFC:

看完这张图你就不淡定了,就光创建一个BFC就有这么多方式?这谁学的动啊?我知道你很急,但是先别急,我们要做的是,找到我们平时开发中常见的几种写法,如果是我清楚了此概念的时候以后该如何写。

咱们先列举一下日常开发中经常用到的几个,例如float,overflow,最后咱们再试一下flow-root。

什么场景下会用到BFC

我们上面介绍了BFC的概念以及如何创建BFC,那么现在到了应用了也就是最有意思的环节,在应用之前,我们先按照常规的思路写出我们的代码:

html 复制代码
<!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>BFC</title>
    <style>
        *{margin:0;padding:0}
        .outer{
            background-color: #ccc;
        }
        .outer > div{
            width:100px;
            height:100px;
            margin: 20px;
        }
        .inner:nth-child(1){
            background-color: orange;
        }
        .inner:nth-child(2){
            background-color: skyblue;
        }
        .inner:nth-child(3){
            background-color: palevioletred;
        }
    </style>
</head>
<body>
    <div class="outer">
        <div class="inner">1</div>
        <div class="inner">2</div>
        <div class="inner">3</div>
    </div>
</body>
</html>

看看效果吧:

好气啊,怎么样式成这样了,我明明想要这种效果的啊:

很多人到这里可能就要找各种方式去尝试了,最终稀里糊涂的把效果实现了,然而之后遇到了依然不知道是什么原因,今天我就带你改变这种学习方式。

首先,我们可以清楚地发现,我们这样书写的代码,div1和div3的margin-top和margin-bottom没有了(塌陷),然后就找了很经典的一句话:

In CSS, when a margin is applied to a child element, it can affect the position of the parent element. This happens because the margins of an element collapse with the margins of its adjacent siblings or its parent, based on certain rules. If the parent element has no padding or border, and the child element has a top margin, then the child element's margin collapses with the parent element's margin, causing the parent element to move along with the child element.

我们从此获得什么信息?如果父元素没有padding或者border的时候,内部子元素的margin会导致父元素跟着移动,这不是我们想要的结果吧,我们先加个border看下效果先:

打开浏览器:

确实,加了border之后就得到了我们想要的效果,很多同学到这儿就结束了,那么思考一下,还有没有更好的方式来解决?当然,既然上面提到了子元素会影响父元素,那么我们BFC的概念是不是可以自然而然的就引出来了,先上代码看效果:

打开浏览器:

确实可以,但是不推荐,为什么不推荐,因为你把握不住,为什么把握不住,因为你用了float之后进而会引发一些其他的问题,这里咱们不展开讨论,你学习一定要找到正确的姿势,这很重要,如果你常年CV而不去思考,那么和一台机器没有任何区别。

再试试overflow吧:

也可以,最后咱们再试试flow-root:

你会发现依然可以,这里咱们就不贴图了,所以到此,你会发现,当我们给父元素开启BFC之后,那么之前产生的一些影响就会被解决,那么在众多的解决方案中,我认为display:flow-root,是当前比较好的方式来处理,为什么?因为当我看到你写了这行代码的时候,我一眼就能明白你要干什么,也就是咱们先前提到的语义化很重要,最后再看一下flow-root的兼容性:

妙,可以放心大胆的食用,什么IE呢?IE已经狗带了。最后留一个思考,我给子元素设置的明明是margin:20,相邻的之间margin不应该是40吗,如果你细心的看完,上文中已经提到了原因。

尾声

在写代码的过程中都会遇到问题,你分析问题,解决问题,找到根源总结以后怎么写是提升你效率和代码质量的关键,很多人可能又会说了,项目工期紧,10天上线,没时间研究这些,这都不是理由,这些思考往往都是留在你工作之外的思考,长期积累才是你慢慢拉开与同行之间的差距,如果说我工作之外只想着刷视频打游戏,那么也不是不行,每个人都有自己选择权利,只是希望在终老的时候不要后悔,那么就是最正确的选择。

相关推荐
GISer_Jing1 小时前
React常见状态管理工具详解
前端·react.js·前端框架
lbh2 小时前
Vue 3 vs React 18:设计理念与开发体验对比
前端·vue.js·react.js
林涧泣2 小时前
【Uniapp-Vue3】iconfont图标库的使用
前端·javascript·uni-app
烛.照1032 小时前
Vue整合Axios
前端·vue.js·chrome
小锋学长生活大爆炸3 小时前
【教程】禁止网页右键和打开调试页面
前端
liuhaikang3 小时前
【鸿蒙HarmonyOS Next实战开发】Web组件H5界面与原生交互-抽奖页面
前端·交互·harmonyos
程序猿000001号4 小时前
Vite:现代前端开发的利器
前端·vite
ufosuai5557 小时前
HTML基本语法
前端·html
慕斯-ing8 小时前
Vue指令v-on
前端·vue.js·经验分享
树毅vs素忆9 小时前
chrome浏览器chromedriver下载
前端·chrome