Skip to content

一文搞懂标准文档流、脱离文档流、BFC 上下文

1.标准文档流:

标准文档流指元素排版布局过程中,元素默认从左到右,从上到下的布局方式,自动换行。

块级元素 和 行内元素 在标准文档流中的表现:

(1)块级元素:

1.块级元素是独占一行的,不与其他元素并列

2.可设置宽高,若不设置宽高则宽度与父元素相同

(2)行内元素:

1.与其他元素并排

2.设置宽高无效,宽高是由内容撑开的

2.脱离标准文档流:

标准文档流限制很多,比如要实现既要并排又要设置宽高,此时就要脱离标准文档流。css 一共有三种手段,使一个元素脱离标准文档流:

1.浮动 float

2.绝对定位 position: absolute

3.固定定位 position: fixed

3.BFC布局

BFC(Block formatting context) 直译为“块格式化上下文”,它是一个独立的渲染区域,在该容器中按照一定规则进行布局排列,容器内元素不会影响外部元素,外部元素不会影响内部元素。

BFC 是一个独立的布局环境(可以说它对标的是标准文档流),其中的元素布局是不受外界的影响,并且在一个 BFC 中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列

注意:可以理解为 BFC 就是一个大容器,它的产生有一定的规则,大容器里面的元素会按照 BFC 的规则进行布局!(常用 overflow:hidden 的方式)

BFC 和标准文档流的关系

BFC(块级格式化上下文)和标准文档流(Normal Flow)都是布局模型,但它们不是同一级别的概念它们分别描述了不同的布局方式和元素排列规则。

标准文档流是 HTML 元素的默认排列方式,它包括块级元素和行内元素。在标准文档流中,元素按照其在 HTML 中出现的顺序进行排列,块级元素会从上到下垂直排列,行内元素会从左到右水平排列。标准文档流中的元素会根据盒模型属性(如 margin、padding)进行布局,元素之间可能发生相互影响。

BFC 是一个布局上下文,它通过一些特定的 CSS 属性或者元素触发。BFC 中的元素在布局时有一些特殊的规则,可以影响元素的排列和布局。BFC 可以包含浮动元素、清除浮动、阻止文本环绕等。

在默认情况下,HTML 元素会按照标准文档流的方式排列。BFC 则需要通过一些方式来触发,例如使用 overflowfloatposition 等属性。不同的元素和属性可以触发不同的布局模型,从而影响元素的排列和布局。触发了 BFC 之后,可以实现一些例如清除浮动、避免 margin 重叠等效果。

什么是 margin 折叠(重叠)

CSS 规范中的 "margin collapsing"(margin 折叠)规则。这是 CSS 中一种定义的布局行为,当相邻的垂直方向上的 margin 相遇时,它们可能会合并为一个 margin 值,从而影响到父元素的布局。这种行为有时可能会令人意外,但它也在某些情况下是有用的。

在 CSS 的标准中,有以下几种情况会发生 margin 折叠:

  1. 相邻兄弟元素的 margin 折叠: 如果两个相邻的兄弟元素(在同一个父元素下)的上下 margin 相遇,它们会合并为一个 margin,取两者中较大的那个值。

  2. 父元素与第一个/最后一个子元素的 margin 折叠: 如果父元素没有 border、padding、inline content、或 clearance 来分隔它与第一个或最后一个子元素的 margin,那么父元素的 margin 可能会与子元素的 margin 相遇并合并。——> 重点关注

    理解:因为父元素没有 border、padding 等,所以子元素是紧贴着父元素的,所以它的 margin 会表现为像是父元素的 margin 一样。

    标准文档流的代码:

    css
    .parent {
      background-color: lightgray;
      /* padding: 20px; 是一种解决方案*/
    }
    .child {
      background-color: lightblue;
      margin: 20px;
      padding: 10px;
    }

    image-20230811174403186

    改为 BFC 布局的代码:

    css
    .parent {
      background-color: lightgray;
      overflow: hidden;
    }
    
    .child {
      background-color: lightblue;
      margin: 20px; /*还是子元素的margin*/
      padding: 10px;
    }

    image-20230811190116155我们发现把容器设置成 bfc 之后,子元素的 margin 不会在 bfc 产生重叠,而是直接应用在自己身上!

  3. 空的块级元素的 margin 折叠: 如果一个没有内容的块级元素的上下 margin 相遇,那么它们会合并为一个 margin。

这些规则是 CSS 标准中的一部分,旨在确保布局的一致性和可预测性。然而,在某些情况下,margin 折叠可能会导致意外的布局结果。为了避免这种情况,可以使用一些技巧,如设置父元素的 border 或 padding,或使用 overflow: hidden 等方法(设置为 BFC)来阻止 margin 折叠。

普通文档流的布局规则:

1.浮动的元素不会被父级元素计算高度(父级高度塌陷)

2.非浮动元素会覆盖浮动元素的位置(浮动元素被覆盖)

3.子元素的 margin 会传递给父级(由于 margin 折叠规则)

4.2 个相邻元素的上下 margin 会重叠(会造成 margin 重叠并最大的)(由于 margin 折叠规则)

BFC 的布局规则:

  1. 在 BFC 中,块级元素从顶端开始垂直地一个接一个的排列。(当然了,即便不在 BFC 里块级元素也会垂直排列,和标准文档流一样)

  2. 外边距折叠:如果两个块级元素属于同一个 BFC,它们的上下 margin 还是会重叠(或者说折叠,和标准文档流一样),以较大的为准。但是如果两个块级元素分别在不同的 BFC 中,它们的上下边距就不会重叠了**(不是 BFC 容器设置 margin,而是原来的元素设置 margin,所以虽然不重叠但是 margin 是在 BFC 内部,而不是 BFC 外面!这点一定注意!)**,而是两者之和。

    原因:因为在 BFC 中,父元素的边距边界会包含其第一个/最后一个子元素的 margin,而不会与其合并。这样可以保持父元素与子元素之间的边界分隔,避免出现意外的布局效果。所以,在 BFC 中,父元素与第一个/最后一个子元素的 margin 折叠是不会发生的。

    下面是利用 BFC 防止重叠 margin 的例子:

    html
    <head>
      <style>
        .block {
          width: 200px;
          height: 200px;
          border: 1px #e8604c solid;
          margin-bottom: 20px;
          overflow: hidden;
        }
        .container {
          border: 1px solid black;
          overflow: hidden;
          margin-bottom: 20px;
        }
        .float-box {
          float: left;
          width: 100px;
          height: 100px;
          background-color: lightblue;
          margin-bottom: 20px;
        }
        .container2 {
          border: 1px solid black;
          overflow: hidden;
          margin-top: 20px;
        }
        .float-box2 {
          float: left;
          width: 100px;
          height: 100px;
          background-color: lightblue;
          margin-top: 20px;
        }
      </style>
    </head>
    <body>
      <div class="container">
        <div class="float-box"></div>
      </div>
      <div class="container2">
        <div class="float-box2"></div>
      </div>
    </body>
    image-20230811225929109
  3. 浮动元素区域不重叠:BFC 的区域(本身就可以是浮动元素)不会与浮动的元素区域重叠,也就是说不会与浮动盒子产生交集,而是紧贴浮动边缘**(其实就是我们常见的多个 float 不会重叠的现象,只是我们平常没有注意它的原理是 BFC 而已,当然不一定是 float 其他 BFC 也可以)**。

    因为 float 本身也是 BFC 布局,所以可以说两个 BFC 之间不会产生重叠,它们只会边线相贴进行排列。

    就像这样,即便高度不一样,右边的也不会占据左边的剩余空间:

    image-20230811230714368

  4. 浮动元素高度计算:计算 BFC 的高度时,浮动元素也参与计算。所以 BFC 可以包含浮动元素。(利用这个特性可以清除浮动,避免出现父元素高度塌陷的问题,也就是给浮动元素外面的父容器加一个 overflow:hidden 即可)

    父元素高度塌陷的情况:

    html
    <head>
      <style>
        .container {
          border: 1px solid black;
          padding: 20px;
        }
        .float-box {
          float: left;
          width: 100px;
          height: 100px;
          background-color: lightblue;
        }
      </style>
    </head>
    
    <body>
      <div class="container">
        <div class="float-box"></div>
        <span
          >This is some text. This is some text. This is some text. This is some
          text.This is some text. This is some text. This is some text. This is
          some text.</span
        >
      </div>
    </body>

    image-20230811223529981

  5. BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。

触发 BFC 的条件:

1.浮动元素(元素的 float 是除 none 以外的值) ——> 同样也是标准的脱离文档流

2.定位元素 (元素的 position 为 absolute 或者 fixed) ——> 同样也是标准的脱离文档流

3.display 为一下其中之一:inline-block, table-cell, table-caption, flow-root,

4.overflow除了 visible 以外的值(hidden, auto, scroll)

BFC 的应用:

1.使用 BFC 避免块之间的 margin 重叠(给每个块分别套上 BFC 容器)——> 重点

2.自适应两栏布局 ——> 需要注意的点

3.自适应布局–文字绕图(其实 float 本身就可以实现,只是套上 BFC 之后不会塌陷,本质上还是清除浮动)

4.清除浮动(给浮动元素套上 BFC 容器)——> 重点

原文链接:https://blog.csdn.net/weixin_44447255/article/details/120447024?spm=1001.2014.3001.5506

用 BFC 实现自适应两栏布局详解

自适应两栏布局

只有左侧元素 float 了 img

页面展示:右侧的会挤占除 float 外的剩余空间

img

解决方法:这是因为 BFC 的区域不会与 float box 重叠。所以我们让 right 单独成为一个 BFC,right 会自动的适应宽度,这时候就形成了一个两栏自适应的布局。

让右侧变成 BFC,设置 overflow:hidden,左侧 float 本身也是一个 BFC

img

img

这样两者只是边线紧贴了!