查看原文
其他

如何理解 css - BFC

前端大全 2022-07-13

The following article is from 前端耳东蜗牛 Author 耳东蜗牛

前置回顾

css视觉格式化模型(visual formatting model)

  • 盒模型的尺寸和类型
  • 定位方案【正常文档流,浮动和绝对定位】
  • 文档树内部元素之间的关系
  • 外部信息(视口大小,图片的固有尺寸等)

总结,visual formatting model决定浏览器如何显示如何处理文档树。盒子类型和定位方案决定元素盒子如何在文档树中显示和放置。

正常文档流 Normal flow

在普通流中,盒子会依次放置。在块格式化上下文中,盒子在垂直方向依次排列;而在行内格式化上下文中,盒子则水平排列。当CSS的 position 属性为 staticrelative,并且 floatnone 时,其布局方式为普通流。

https://www.w3.org/TR/CSS2/visuren.html#block-formatting

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

翻译一下:正常文档流下,盒模型归属到格式化上下文。块级盒子参加块级格式化上下文。内联盒子参加内联格式化上下文。

FC

https://drafts.csswg.org/css-display/#formatting-context

A formatting context is the environment into which a set of related boxes are laid out. Different formatting contexts lay out their boxes according to different rules.

格式化上下文是决定盒子之间如何布局的环境,不同的格式化上下文如何布局盒子由自身的规则来决定。

BFC

https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context

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

https://zhuanlan.zhihu.com/p/25321647

具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。

BFC规则

  • 内部盒子会在垂直方向排列
  • 同一个BFC上环境下的元素可能发生margin collapse
  • BFC就是页面上的一个隔离的独立容器,里外互相不受影响
  • 计算BFC的高度时,考虑BFC所包含的所有子元素,连浮动元素也要参与计算。
  • 当元素不是BFC的子元素时,浮动元素高度不参与BFC计算(常见的盒子塌陷问题)
  • 每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • BFC的区域不会与float box重叠。

BFC触发条件

  • 根元素html
  • float元素不为none
  • position为absolute或fixed
  • display为inline-block, table-cell, table-caption, flex, inline-flex
  • overflow不为visible

如何理解BFC的应用

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>

    </style>
  </head>

  <body>

  </body>
</html>
  • 内部盒子会在垂直方向排列
  • 同一个BFC上环境下的元素可能发生margin collapse
  • BFC就是页面上的一个隔离的独立容器,里外互相不受影响

可能我们的页面是很复杂的页面,但是初始我们的页面书写都是基于上面的结构。此时整个文档流只有一个BFC环境,那就是html。所以内部的元素存在盒子塌陷,浮动等问题,是根据规则来的。所以我们在内部创建了新的BFC根据上面规则第三条。就可以解决相关的问题。

例子1:margin重叠

  • 同一个BFC上环境下的元素可能发生margin collapse
  • BFC就是页面上的一个隔离的独立容器,里外互相不受影响
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      div{
          width: 100px;
          height: 100px;
          background: yellowgreen;
          margin: 100px;
      }
    </style>
  </head>
  <body>
    <div></div>
    <div></div>
  </body>
</html>

现在我们给其中一个div创建BFC新的环境。

<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      div{
          width: 100px;
          height: 100px;
          background: yellowgreen;
          margin: 100px;
          overflow: hidden;
          display: inline-block;
      }
    </style>
  </head>
  <body>
    <div></div>
    <div></div>
  </body>
</html>

例子2:BFC高度计算包含浮动元素

  • 计算BFC的高度时,考虑BFC所包含的所有子元素,连浮动元素也要参与计算。
  • 当元素不是BFC的子元素时,浮动元素高度不参与BFC计算(常见的盒子塌陷问题)
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      .parent {
        background: gray;
      }

      .child {
          float: left;
          width: 100px;
          height: 100px;
          background: yellowgreen;
          margin: 100px;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      <div class="child"></div>
    </div>
  </body>
</html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      .parent {
        background: gray;
        overflow: visible;
      }

      .child {
          float: left;
          width: 100px;
          height: 100px;
          background: yellowgreen;
          margin: 100px;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      <div class="child"></div>
    </div>
  </body>
</html>

例子3:自适应两栏布局

  • 每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • BFC的区域不会与float box重叠。
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      .left {
        width: 100px;
        height: 150px;
        float: left;
        background: gray;
      }

      .right {
        height: 300px;
        background: rgb(170, 54, 236);
        background: yellowgreen;
      }
    </style>
  </head>
  <body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
  </body>
</html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      .left {
        width: 100px;
        height: 150px;
        float: left;
        background: gray;
      }

      .right {
        overflow: hidden;
        height: 300px;
        background: rgb(170, 54, 236);
        background: yellowgreen;
      }
    </style>
  </head>
  <body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
  </body>
</html>

BFC总结

BFC就是页面上的一个隔离的独立容器,里外互相不受影响

整体的思路就是在现有的html BFC环境下,为了处理一些问题,触发BFC条件,生成新的BFC环境。来以此隔离解决原有的一些问题。


- EOF -

推荐阅读  点击标题可跳转

1、CSS: 潜藏着的BFC

2、有趣的 CSS 数学函数

3、TailwindCSS v3.0 正式发布!一大波新特性来袭!


觉得本文对你有帮助?请分享给更多人

推荐关注「前端大全」,提升前端技能

点赞和在看就是最大的支持❤️

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存