BFC?

BFC是前端面试中CSS部分的一个常考项,但是这个概念却是很不好理解的。

官方的定义

BFC (block formatting context) 块级格式化上下文。

在说BFC之前,先要说一下它的‘父亲’,FC(formatting context) 格式化上下文。FC用来表示页面中的某块区域是用什么格式来进行渲染布局的,常见的FC有: BFC,IFC(行级格式化上下文),GFC(网格布局格式化上下文)和FFC(自适应布局格式化上下文)。这四个好像是和display有着一些关系。由于我只对BFC有一些粗浅的理解,IFC,FFC,GFC这三个兄弟这里就不说了。

CSS视觉格式化模型与BFC

此处参考MDN

在说BFC之前必须要了解CSS视觉格式化模型。如果已懂可自行跳过。

CSS视觉格式化模型(visual formatting model)是用来将文档展示到视觉媒体上的计算规则,它会根据盒子模型将文档的元素生成一个个的盒子(Box)。

一个页面是由很多个的Box构成的,每一个Box都会有自己的类型,Box的类型取决于这个Box是个什么元素以及这个Box的display属性是什么。不同类型的Box就会有不同的FC来控制它的布局。所以,BFC也就是用来控制block-level的Box的是如何进行布局的。

下面解释几个定义

  • block-level box

块级盒子由块级元素(block-level element)生成。一个块级元素至少生成一个块级盒子,list-item除了自己的主块级盒子外,还有一个标记盒子。

-block-level element

块级元素,也就是display属性为 block,list-item,table的这些元素

OK,到这里已经会比较清晰的了解到BFC的作用范围了

更通俗的理解BFC

我看过很多的博客讲解BFC,但是还是更喜欢张鑫旭老师解释的。

一个BFC就像是一个结界一样,可以控制其内部的block-level Box不去影响结界外部的元素的正常布局。而这也是为什么我们要去使用BFC的原因(因为没有结界,一个包含块内的元素可能会影响其他元素的正常布局)。

那么,也就是说,不一定所有的块级盒子都会产生这个结界。

什么情况下会产生BFC呢?

  1. <html> 根元素 (最外层的结界)
  2. position 值是absolute或fixed (也就是说,在我们不设置特殊的position值时,都不会产生BFC)
  3. float 元素
  4. display值为 inline-block 、 table-cell、 table-caption (说实话后面俩好像都没用过)
  5. overflow的值不是visible
  6. flex的直接子元素以及grid的直接子元素

BFC下有哪些表现?

最基本的就是下面这五个特性:

  1. 内部的block-level Box会在垂直方向一个接一个的放置
  2. 上下margin重叠(取大值)
  3. 不同BFC下互不干扰布局
  4. 计算BFC高度时会将浮动元素也算入进去
  5. 不与浮动元素重叠(这个应该也是因为3)
  6. BFC内block-level Box在无padding,border的情况下,其内部box会将margin-top和margin-bottom(最上面和最下面的元素)转移到父元素且发生重叠。会一层一层往上转移知道有box具有padding和border属性。但是当父元素构成BFC时,无法转移
  • 案例1、文字环绕 (float真的是实现文字环绕效果很方便的一个手段)
/*css*/
  .wrap {
    width: 100px;
    background: red;
    color: aliceblue;
  }

  .float {
    float: left;
    width: 50px;
    height: 100px;
  }
// html
<div class="wrap">
    <div class="float">假装自己是个图片</div>
    <!-- <div class="text">我是一段很长很长的文字我是一段很长很长的文字我是一段很长很长的文字</div> -->
    <div class="text">我很短</div>
 </div>

看下面这两张图的比较:float可以导致父元素的高度崩塌,又因为行框盒子(这里指文字)和浮动元素的不可重叠性,所以在文字比较长时会有环绕的效果。

上面的父元素高度崩塌的解决方案也很简单,就是给文字的Box设置一个after伪元素。

.text::after {
  content: "";
  display: block;/*clear属性只作用在块级元素上*/
  clear: both;
}
long.png
short.png

可不可以利用BFC达到相似的效果

 .wrap {
    display: inline-block;/*形成BFC*/
    width: 100px;
    background: red;
    color: aliceblue;
  }

因为4的原因,使得.wrap 元素形成BFC时高度会计算其内部的float元素,故解决了塌陷问题。

BFC1.png

这个可以说是一个很方便的解决方案

案例2、自适应两栏布局

<!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>
    * {
      margin: 0;
      padding: 0;
    }

    .container {
      height: 100vh;
    }
    .menu {
      width: 200px;
      float: left;
      background: rgb(0, 255, 221);
      height: 100%;
      animation: changeW 3s infinite alternate;
    }
  /*模拟菜单拖拽*/
    @keyframes changeW {
      0% {
        width: 200px
      }

      100% {
        width: 500px;
      }
    }

    .content {
      overflow: hidden;
      height: 100%;
      background: rgb(238, 115, 8);
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="menu">我是菜单</div>
    <div class="content">我是内容</div>
  </div>
</body>
</html>

效果

这个就利用了3或者5的特性。现在由于flex布局的普及,可能我们不会再用这样的方法了。。。

案例3、外边距去哪了?

code:

<!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>
    .son {
      margin: 10px;
      width: 100px;
      height: 100px;
      background: paleturquoise;
    }

   .normal {
      margin: 10px 0;
    }
    .son2 {
      margin: 10px 0;
    }

    .BFC {
      overflow: hidden;
    }
  </style>
</head>
<body>
  <div class="normal">
    <div class="son"></div>
  </div>
  
  <div class="BFC">
    <div class="son2">
      <div class="son2">
        <div class="son"></div>
      </div>      
    </div>
  </div>

  <div class="normal">
    <div class="son"></div>
  </div>

  <div class="normal">
      <div class="son"></div>
    </div>
</body>
</html>
效果图.png

效果解析:

如图,3,4两个box在垂直方向发生margin重叠间距只有10px符合BFC(此处为html根元素构成BFC)1,2两个特性

我在son和normal两个类均设置上下边距为10px,但是由于BFC中的6的特性,使得子元素上下外边距传递给父元素且发生重叠,最后两个.normal box之间的边距也就是为10px

最后,因为给.BFC box 设置overflow: hidden;使其构成BFC,让其直接子元素的上下外边距无法传递给自己,所以,这个box和其相邻box之间的边距变成了20px

结语

本文参考MDN文档以及张鑫旭老师的《CSS世界》一书。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • relative:生成相对定位的元素,通过top,bottom,left,right的位置相对于其正常位置进行定位...
    zx9426阅读 911评论 0 2
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,629评论 1 92
  • 什么是BFC BFC全称是Block Formatting Context,即块格式化上下文。它是CSS2.1规范...
    陌客百里阅读 526评论 3 4
  • 转载自(http://web.jobbole.com/83274/) BFC BFC全称是Block Format...
    居客侠阅读 2,096评论 0 20
  • 昨天 是否还在敲击你的心房 用它沾满鲜血的双手 撕碎心底不堪一击的信仰 伸出无比肮脏的舌头 掩盖曾经散落满地的真相...
    宋哇哇阅读 113评论 2 2