CSS - BFC详解

FC-Fomatting Context

FC的全称是 Formatting Context,元素在标准流里面都是属于一个FC的.

Boxes in the normal flow belong to formatting context,which may be block or inline,but not both simulaneously. Block-level boxes participate in a block formaatting context. Inline-level boxes participate in an inline formatting context.

在标准流中的盒子都属于一个格式化上下文,不论这个元素是 块级元素或者 行内级元素,但是它们属于的格式化上下文是不同的.块级盒子属于 块级 格式化上下文.行内级盒子 属于 行内级格式化上下文.

块级元素的布局属于 Block Fomatting Context (BFC)

也就是 blcok level box 都是 在**BFC **中布局的.

行内级元素的布局属于Inline Formatting Context(IFC)

inline level box 都是在IFC 中布局的.

BFC - Block Fomatting Context - 哪里有BFC?

block level box 都是在BFC 中布局的,BFC布局 在HMTl文档中的位置

FLoats,absolutely positioned elements,block containers(such as inline-blocks,table-cess,and table-captions)that are not block boxes,and block boxes with 'overflow' other than 'visible'(except when tha values has been propagated to the viewport)establish new block formatting contexts for their contents.

浮动元素,决定定位元素,不是块级元素盒子的元素(比如行内级元素,table-cells和 table-captions)和没有把overflow 属性设置为'visible'的块级盒子 都会给他们的内容 重新创建一个新的 格式化块级上下文.

这里强调一下 div 的overflow 属性的默认值为 visible,所以div 是不会创建新的 BFC的.

MDN 上有整理出在那些具体情况下 会创建 BFC:

  • 根元素(< html >)
  • 浮动元素(元素的 float 不是none)
  • 绝对定位元素(元素的position 为 absolute,或fixed)
  • 行内块级元素(元素的display 为inline-block)
  • 表格单元格(元素的display 为table-cell,HTML 表格单元格默认为该值),表格标题(元素的display 为 table-caption,HTML表格标题默认为该值)
  • 匿名表格元素(元素的display 为 table,table-row,table-row-group,table-header-group,table-footer-group(分别是HTML table,row,tbody,thead,tfoot的默认属性)或inline-table)
  • overflow 计算值(Computed)不为 visible的块元素
  • 弹性元素(display 为flex 或 inline-flex元素的直接子元素)
  • 网格元素(display 为grid 或 inline-grid 元素的直接子元素)
  • display 值为 flow-root 的元素

BFC 有什么用?

官方文档对BFC 作用的 描述如下:

In a block fomatting context,boxes are laid out one after the other,vertically,beginning at the top of a containing block.The vertical distance between two sibling boxes is determined by the 'margin'properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.

In a blcok formatting context,each box's left outer edge touches the left edge of the containing block(for right-to-left formatting,right edges touch).This is true even in the presence of floats (although a box's line boxes may shrink due to the floats),unless the box establishes a new block formatting context(in which case the box itself my become narrower due to the floats).

简单翻译如下:

  • 在BFC 中,box 会在垂直方向上一个挨着一个的排布.
  • 垂直方向的间距 由 margin 属性和决定.
  • 在同一个BFC 中,相邻两个box 之间的margin 会折叠(collcapse)
  • 在BFC 中,每个元素的左边缘是紧挨着包含块的左边缘的.

BFC的具体作用:

  • 通过 新建一个BFC 解决margin 的折叠问题
  • 通过 新建一个BFC 解决浮动高度塌陷问题

BFC 的作用一: 解决折叠问题

在同一个BFC 中,相邻两个box 之间的margin 会折叠(collapse)

官方文档有明确说

Vertical margins between adjacent block-level boxes in a block formatting context collapse.

那么如果我们让两个box 是不同的BFC 呢? 那么就可以解决折叠问题

demo

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>Document</title>
  <style>
    /* .box {
      overflow: auto;
    } */

    .container {
      overflow: auto;
    }

    .box1 {
      height: 200px;
      width: 400px;
      background-color: orange;

      margin-bottom: 30px;
    }

    .box2 {
      height: 150px;
      background-color: purple;

      margin-top: 20px;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box1"></div>
  </div>
  <div class="box2"></div>
</body>
</html>

BFC 的作用二: 解决浮动高度塌陷

BFC 解决高度塌陷需要满足两个条件:

  • 浮动元素的父元素触发BFC,形成独立的块级格式化上线文(Block Fomatting Context)
  • 浮动元素的父元素的高度是auto的

BFC的高度是auto 的情况下,是按如下方法计算高度的

  • 1.如果只有inline-level 元素,是行高的顶部到底部的距离
  • 2.如果有block-level,是由最顶层的块上边缘和最底层块盒子的下边缘的距离.
  • 3.如果有绝对定位元素,将被忽略. -- 为啥不能解决绝对定位元素的高度缺陷
  • 4.如果有浮动元素,那么会增加高度以包含这些浮动元素的下边缘 -- 解决浮动高度塌陷
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>Document</title>
  <style>
    .container {
      background-color: orange;
      position: relative;

      overflow: auto;
    }

    .item {
      width: 400px;
      height: 200px;
      box-sizing: border-box;
      border: 1px solid #000;
      float: left;
      background-color: #f00;

      /* position: absolute; */
    }
  </style>
</head>
<body>
  
  <div class="container clear_fix">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
是否能够显示?已解决浮动高度塌陷: 没有解决
</body>
</html>
相关推荐
10年前端老司机2 小时前
10道js经典面试题助你找到好工作
前端·javascript
小小小小宇7 小时前
TS泛型笔记
前端
小小小小宇7 小时前
前端canvas手动实现复杂动画示例
前端
codingandsleeping8 小时前
重读《你不知道的JavaScript》(上)- 作用域和闭包
前端·javascript
小小小小宇8 小时前
前端PerformanceObserver使用
前端
zhangxingchao9 小时前
Flutter中的页面跳转
前端
烛阴9 小时前
Puppeteer入门指南:掌控浏览器,开启自动化新时代
前端·javascript
全宝10 小时前
🖲️一行代码实现鼠标换肤
前端·css·html
小小小小宇11 小时前
前端模拟一个setTimeout
前端
萌萌哒草头将军11 小时前
🚀🚀🚀 不要只知道 Vite 了,可以看看 Farm ,Rust 编写的快速且一致的打包工具
前端·vue.js·react.js