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>
相关推荐
IT_陈寒15 分钟前
JavaScript开发者必知的5个性能杀手,你踩了几个坑?
前端·人工智能·后端
跟着珅聪学java19 分钟前
Electron 精美菜单设计
运维·前端·数据库
日光倾19 分钟前
【Vue.js 入门笔记】闭包和对象引用
前端·vue.js·笔记
一只程序熊26 分钟前
UniappX 未找到 “video“ 组件,已自动当做 “view“ 组件处理。请确保代码正确,或重新生成自定义基座后再试。
前端
林小帅27 分钟前
【笔记】xxx 技术分享文档模板
前端
雾岛心情33 分钟前
【HTML&CSS】HTML为文字添加格式和内容
前端·css·html
心.c41 分钟前
如何在项目中减少 XSS 攻击
前端·xss
Rsun045511 小时前
Vue相关面试题
前端·javascript·vue.js
TON_G-T1 小时前
前端包管理器(npm、yarn、pnpm)
前端
卤炖阑尾炎1 小时前
Web 技术基础与 Nginx 网站环境部署全解析
前端·nginx·microsoft