CSS | 请解释一下何为BFC以及它是如何工作的?

区块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视 CSS 渲染的一部分,是块级盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

1. 背景介绍

我们常常说文档流的时候其实分为定位流、浮动流和普通流三种。其中普通流就是指BFC中的FC。FC是formatting context的首字母缩写,直译过来是格式化上下文,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。

常见的FC有BFC、IFC,还有GFC和FFC。BFC是block formatting context,也就是块级格式化上下文,是用于布局块级盒子的一块渲染区域。

参考资料:区块格式化上下文 - CSS:层叠样式表 | MDN

2. 知识剖析

一:BFC是什么

BFC是可视化CSS渲染网页的一部分,它是一个区域,块级布局,相互浮动在这个区域发生。

一个BFC块区域包含所有里面的元素,除子元素创建了新的BFC。(因为各个BFC是一个独立的区域,BFC之间相互不影响)。

所以,由于html(根元素)是独立的BFC,在里面的浮动,块级布局等才会相互影响,若新创建BFC,则相邻BFC之间的浮动元素,或是其他元素将不会影响。如,相邻两个块级元素的外边距折叠的情况将不会发生。

参考文献:深入理解BFC - 博客园 | BFC (Block formatting context)是什么? - 博客园

二:触发条件

满足下列条件之一就可触发BFC(造成元素变成BFC布局的原因):

【1】文档的根元素,即HTML元素

【2】浮动元素,即float的值不为none的元素

【3】绝对定位元素,即position 值为 absolute 或 fixed 的元素

【4】行内块元素(display 值为 inline-block 的元素)。

【5】表格单元格(display 值为 table-cell,HTML 表格单元格默认值)。

【6】表格标题(display 值为 table-caption,HTML 表格标题默认值)。

【7】contain 值为 layout、content 或 paint 的元素。

【8】overflow值不为visible 或 clip 的块级元素。

【9】display的值为flow-root的元素。 ——display:flow-root不干别的,专门用来触发BFC。

【10】弹性元素(display 值为 flex 或 inline-flex 元素的直接子元素),如果它们本身既不是弹性、网格也不是表格容器。

【11】网格元素(display 值为 grid 或 inline-grid 元素的直接子元素),如果它们本身既不是弹性、网格也不是表格容器。

格式化上下文影响布局,通常,我们会为定位和清除浮动创建新的 BFC,而不是更改布局,因为它将:●包含内部浮动。 ●排除外部浮动。 ●阻止外边距重叠。

备注: 弹性 / 网格容器(display:flex/grid/inline-flex/inline-grid)建立新的弹性/网格格式化上下文,除布局之外,它与区块格式化上下文类似。弹性/网格容器中没有可用的浮动子级,但排除外部浮动和阻止外边距重叠仍然有效。

总结:CSS触发BFC(Block Formatting Context ——块格式化上下文)的方法主要包括以下几种‌

  1. 根元素‌:根元素(即<html>元素)自身就是一个BFC。

  2. 浮动元素‌:当元素的float属性值不为none时,即设置为左浮动或右浮动,这样的元素会触发BFC。

  3. 绝对定位元素‌:当元素的position属性值为absolutefixed时,这样的绝对定位元素会触发BFC。

  4. 行内块元素‌:当元素的display属性值为inline-block时,这样的行内块元素会触发BFC。

  5. 表格单元格和表格标题‌:当元素的display属性值为table-celltable-caption时,这样的表格单元格和表格标题也会触发BFC。

  6. 弹性盒子容器‌:当元素的display属性值为flexinline-flexgridinline-grid时,这样的弹性盒子容器和网格容器会触发BFC。

  7. overflow属性‌:当元素的overflow属性值不为visible时,如设置为autoscrollhidden,这样的元素也会触发BFC。

这些方法涵盖了CSS中触发BFC的主要方式,包括通过元素的特定属性设置来创建BFC,从而影响布局和样式表现‌。

三:BFC的作用

资料参考:BFC是啥?display: flow-root是啥?-CSDN博客

● 包含浮动元素(清除浮动)——父元素包裹住子元素

BFC会根据子元素的情况自适高度,这个特性是对父元素使用overflow:hidden/auto/scroll、 float:left/right 样式可以闭合浮动的。

用 BFC 包住浮动元素,儿子是浮动元素,正常情况下,浮动元素会脱离文档流离开爸爸的怀抱。但是BFC的功能就是不让儿子跑出爸爸的怀抱。

● 不被浮动元素覆盖——兄弟元素之间划清界限

浮动元素会无视兄弟元素的存在, 覆盖在兄弟元素的上面, 为该兄弟元素创建BFC 后可以阻止这种情况的出现。

四:BFC的规则

资料参考:bfc规则详解_-CSDN博客

● 内部的Box会在垂直方向,一个接一个地放置。 就是我们平常div一行一行块级放置的样式。Box垂直方向的距离由margin决定。

● 属于同一个BFC的两个相邻Box的margin会发生重叠。

● 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。就是元素左margin和包含块左border接触,即使存在浮动也是如此。左浮动就是靠左,右浮动就是靠右,

● BFC的区域不会与外部的float box重叠。应用于两列布局

● BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之,也如此。上下margin不影响,浮动不覆盖。

● 计算BFC的高度时,浮动元素也参与计算,也就是说,在BFC内部的浮动元素也计算在BFC的宽度之内。如父元素高度塌陷,清除浮动。父元素高度由内部撑开,计算BFC高度,内部浮动的子元素也参加。

3. 常见问题

1. 外边距折叠(Collapsing Margins)。

2. 让一个没有设置高度的容器包含浮动元素。

3. 阻止文字环绕。

4. 解决方案

1. 外边距折叠

外边距折叠有很多种情况,最简单的就是上下两个盒子,上面的设置了margin-bottom,下面的设置了margin-top,这时候总的外边距并不是两者相加,而是取最大的外边距作为总的外边距。(假设外边距的设置为正值)

下面的代码发生了外边距折叠。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>外边距折叠</title>
    <style>
      .container {
        background-color: red;
        width: 400px;
      }
      p {
        font-size: 30px;
        background: yellow;
        margin: 100px 0;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <p>盒子1</p>
      <p>盒子2</p>
    </div>
  </body>
</html>

发生了外边距折叠(上) 

下面的代码通过使用overflow: hidden;新创建一个BFC,从而实现阻止外边距折叠。(overflow: hidden;意思是:如果盒子的内容超出盒子,则这部分内容隐藏。) 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>外边距折叠</title>
    <style>
      .container {
        background-color: red;
        width: 400px;
      }
      p {
        font-size: 30px;
        background: yellow;
        margin: 100px 0;
      }
      .bfc {
        overflow: hidden;
	    }
    </style>
  </head>
  <body>
    <div class="container">
      <p>盒子1</p>
      <div class="bfc">
    	  <p class="bfc">盒子2</p>
      </div>
    </div>
  </body>
</html>

 使用BFC阻止外边距折叠(下)

2. 容器无高度包含浮动元素

无BFC,容器无高度包含浮动元素会产生如下效果:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>容器无高度包含浮动元素</title>
  <style>
    .container {
      background-color: red;
      width: 400px;
      outline: 1px dashed red;
      margin-top: 10px;
    }
    p {
      font-size: 30px;
      background: yellow;
      margin: 100px;
      float: left;
    }
  </style>
</head>
<body>
  <div class="container">
    <p>盒子1</p>
    <p>盒子2</p>
  </div>
</body>
</html>

高度坍塌现象 

可以看到,由于浮动元素是脱离普通文档流的,所以.container盒子发生了塌陷,高度变为0。如何阻止这种情况发生呢,可以给上面的代码.container盒子添加了一条样式overflow: hidden,解决了容器盒子塌陷的问题。

效果图如下: 

3. 阻止文字环绕

左图右文,文字环绕图片,效果图:

代码如下: 

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>文字环绕图片</title>
    <style>
      .container {
        width: 600px; /* 容器宽度 */
        margin: 20px auto; /* 居中显示 */
      }
      .float-left {
        float: left; /* 图片向左浮动 */
        margin-right: 15px; /* 图片右侧留白 */
        margin-bottom: 10px; /* 图片下方留白 */
        width: 200px; /* 控制图片宽度 */
        height: auto; /* 高度自适应 */
      }
    </style>
  </head>
  <body>
    <div class="container">
      <img src="nuidc.jpg" alt="示例图片" class="float-left" />
      <p>
        这里是一段示例文字,它将会环绕在图片的周围。你可以根据需要添加更多的文字内容,看看文字是如何环绕图片布局的。文字会根据图片的位置和大小自动调整排列,以适应页面的布局。
        效果说明 1. ‌浮动方向‌:图片设置为 float: left 后,会脱离文档流并向左浮动,文字会自动环绕在图片右侧。 2. ‌间距控制‌:通过 margin-right 和 margin-bottom 在图片周围创建空隙,避免文字紧贴图片。 3. ‌容器宽度‌:父容器设置固定宽度可防止布局溢出。
        注意事项 1. ‌清除浮动‌:如果浮动图片后还有其他非浮动内容,可能需要用 clear: both 清除浮动。 2. ‌响应式设计‌:建议为图片设置 max-width: 100% 和 height: auto 实现自适应。 3. ‌图文间距‌:根据设计需求调整 margin 值,推荐使用 em 或 rem 单位。  
        最终效果:文字会紧密围绕在图片周围,类似杂志排版样式。
      </p>
    </div>
  </body>
</html>

有时候我们不需要文字环绕,就想让文字老老实实待在右边,这时我们可以加入.text { overflow: hidden;}

效果如下: 

4. 扩展思考

为什么用overflow触发而不用其他的?

因为其他如:float,positon等等会影响布局,达不到我们想要的效果。 

5. 更多讨论

1. 什么是IE的haslayout?

hasLayout可以简单看作是IE5.5/6/7中的BFC(Block Formatting Context)。也就是一个元素要么自己对自身内容进行组织和尺寸计算(即可通过width/height来设置自身的宽高),要么由其containing block来组织和尺寸计算。

而IFC(即没有拥有布局)而言,则是元素无法对自身内容进行组织和尺寸计算,而是由自身内容来决定其尺寸(即仅能通过line-height设置内容行距,通过行距来支撑元素的高度;也无法通过width设置元素宽度,仅能由内容来决定而已)

2. overflow的auto还是visible可以触发bfc?

auto,hidden,scroll可以触发

3. 利用浮动再触发bfc用来干嘛?

用来实现左列定宽,右列自适应布局


参考资料

—— CSS | 详解何为BFC以及BFC能解决什么问题 - CSDN博客 ——

深入理解BFC - 小火柴的蓝色理想 - 博客园 | BFC (Block formatting context) 是什么 - 博客园

BFC是啥?display: flow-root是啥?-CSDN博客

display - CSS:层叠样式表 | MDN | display 的新属性值 flow-root

BFC--块级格式化上下文-CSDN博客 | 学习块格式化上下文(BlockFormattingContext) - 简书

关于元素间的边距重叠问题与BFC-腾讯云开发者社区 | 理解CSS布局和BFC - 前端开发社区

如何理解块级格式化上下文BFC(block formatting context) - 知乎 |  深入理解 BFC - 知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值