乐趣区

关于前端:CSS中的FC到BFC

本文首发国内开源代码托管平台 Gitee
文章地址:
https://gitee.com/gooder4j/compose-hub/issues/I4U78Q

感觉不错的话,你的 star 是对我最大的反对!

Formatting Context 简略了解,就是定义了布局规定的一片区域。它的类型包含:

  • Block Formatting Context,简称 BFC
  • Inline Formatting Context,简称 IFC
  • Flex Formatting Context,简称 FFC
  • Grid Formatting Context,简称 GFC

Block Formatting Context(BFC)

A block formatting context is a part of a visual CSS rendering of a web page. It’s the region in which the layout of block boxes occurs and in which floats interact with other elements.

Block Formatting Context(BFC) 是 web 页面可视化 CSS 渲染的一部分,它是块级盒占据和 float 与其余元素相互作用的区域。

从定义来看,BFC 是一块 area、region,也就是页面上的一部分区域,这块区域上有块级盒、float,并且规定了它们的布局规定。

Formatting contexts affect layout, but typically, we create a new block formatting context for the positioning and clearing floats rather than changing the layout, because an element that establishes a new block formatting context will:

  • contain internal floats.
  • exclude external floats.
  • suppress margin collapsing.

Formatting context 影响布局,但一般来说,咱们会创立一个新的 BFC,用于定位和革除 float 而不是来扭转布局,因为建设了 BFC 的一个元素会:

  • 蕴含外部 float
  • 排除内部 float
  • 阻止外边距重叠

上面用例子开展阐明下面三条规定。

BFC 的三条规定

蕴含外部 float

  1. 当一个元素没有 BFC 时:

HTML

<section>
    <div class="box">
        <div class="float">I am a floated box!</div>
        <p>I am content inside the container.</p>
    </div>
</section>

CSS

section {height: 150px;}

.box {background-color: rgb(224, 206, 247);
    border: 5px solid rebeccapurple;
}

.float {
    float: left;
    width: 200px;
    height: 100px;
    background-color: rgba(255, 255, 255, .5);
    border: 1px solid black;
    padding: 10px;
}
  1. 当元素的属性 overflow 不等于 visible 时,该元素会创立 BFC:

HTML

<section>
    <div class="box">
        <div class="float">I am a floated box!</div>
        <p>I am content inside the container.</p>
    </div>
</section>
<!-- 增加新的 section 比照 -->
<section>
    <div class="box" style="overflow: auto;">
        <div class="float">I am a floated box!</div>
        <p>I am content inside the container.</p>
    </div>
</section>
  1. 应用 display: flow-root 创立 BFC。

    尽管块级元素的 overflow 不为 visibleclip时能够创立 BFC,然而它有很大的毛病——偏离 overflow 的原意 overflow 是用于设定内容超出容器时的动作,如果单纯为了创立 BFC 而应用overflow,那么最终款式成果可能出其不意,并且足够蛊惑误导将来看这段代码的小伙伴。

    应用 display: flow-root 的益处:创立 BFC 并且不会有副作用。

HTML

<section>
    <div class="box">
        <div class="float">I am a floated box!</div>
        <p>I am content inside the container.</p>
    </div>
</section>
<section>
    <div class="box" style="overflow: auto;">
        <div class="float">I am a floated box!</div>
        <p>I am content inside the container.</p>
    </div>
</section>
<!-- 增加新的 section 比照 -->
<section>
    <div class="box" style="display: flow-root">
        <div class="float">I am a floated box!</div>
        <p>I am content inside the container.</p>
    </div>
</section>

排除内部 float

当一个元素挨着另外一个 float 时:

HTML

<section>
    <div class="float">I am float</div>
    <div class="box">
        <p>Normal</p>
    </div>
</section>

CSS

section {height: 150px;}

.box {background-color: rgb(224, 206, 247);
    border: 5px solid rebeccapurple;
}

.float {
    float: left;
    overflow: hidden;
    margin-right: 25px;
    width: 200px;
    height: 100px;
    background-color: rgba(255, 255, 255, .75);
    border: 1px solid black;
    padding: 10px;
}

通过 display: flow-root 为元素加上 BFC 后:

阻止外边距折叠

外边距折叠指垂直方向的外边距折叠,原则上是可能折叠就折叠,次要有三种状况[3]

  1. 相邻元素外边距折叠,这是最常见的;
  2. 父元素和子孙元素没有离开(被边框、内边距、BFC 等离开)是外边距也会折叠;
  3. 空元素没有内容(没有 content,边框,内边距时)它的上下边距会折叠在一起。

看例子,当没有 BFC 时:

HTML

<div class="blue"></div>
<div class="outer">
    <div class="inner">red inner</div>
</div>

CSS

.blue {
    height: 50px;
    margin: 10px 0;
    background: blue;
}

.outer {background: red;}

.inner {
    height: 80px;
    margin: 10px 0;
    background-color: coral;
}

当创立了 BFC 后,外边距的折叠会被阻止:

创立 BFC

A block formatting context is created by at least one of the following:

  • The root element of the document (<html>).
  • Floats (elements where float isn’t none).
  • Absolutely positioned elements (elements where position is absolute or fixed).
  • Inline-blocks (elements with display`: inline-block`).
  • Table cells (elements with display`: table-cell`, which is the default for HTML table cells).
  • Table captions (elements with display`: table-caption`, which is the default for HTML table captions).
  • Anonymous table cells implicitly created by the elements with display: table, table-row, table-row-group, table-header-group, table-footer-group (which is the default for HTML tables, table rows, table bodies, table headers, and table footers, respectively), or inline-table.
  • Block elements where overflow has a value other than visible and clip.
  • display: flow-root.
  • Elements with contain: layout, content, or paint.
  • Flex items (direct children of the element with display:flex or inline-flex) if they are neither flex nor grid nor table containers themselves.
  • Grid items (direct children of the element with display: grid or inline-grid) if they are neither flexnor grid nor table containers themselves.
  • Multicol containers (elements where column-count or column-width isn’t auto, including elements with column-count: 1).
  • column-span: all should always create a new formatting context, even when the column-span: all element isn’t contained by a multicol container (Spec change Chrome bug[4])

如下状况会创立 BFC:

  • 文档的根元素(<html>
  • Float(元素的 float 属性值不为none)。
  • 相对定位元素(元素的 position 属性值为 absolute 或者fix)。
  • Inline-block(元素带有display:inline-block)。
  • 表格单元(元素带有display: table-cell,它是 HTML 表格单元的默认属性值)。
  • 表格题目(元素带有display: table-caption,它时 HTML 表格题目的默认属性值)。
  • 匿名的表格单元,它会隐式地被 display: table, table-row, table-row-group, table-header-group, table-footer-group(它们别离是表格、表格行、表格体、表格脚的默认属性值),inline-table 所创立。
  • 块级元素的 overflow 属性不为 visibleclip
  • display: flow-root
  • 元素有 contain: layout, content 或者paint
  • 自身即不是弹性容器、不是网格容器、也不是表格的 Flex 我的项目(元素带有 display: flex 或者 inline-flex 的间接子元素)。
  • 自身即不是弹性容器、不是网格容器、也不是表格的 Grid 我的项目(元素带有 display: grid 或者 inline-grid 的间接子元素)
  • 多列容器(元素的 column-count 或者 column-width 不为 auto,包含column-count: 1 的元素)。
  • column-span: all应该永远创立一个新的 formatting context,即便 column-span: all 元素没有被多行容器所包含(标准扭转[4],Chrome Bug[5])。

Inline Formatting Context(IFC)

Inline formatting contexts exist inside other formatting contexts and can be thought of as the context of a paragraph. The paragraph creates an inline formatting context inside which such things as <strong>, <a>, or <span> elements are used on text.

Inline formatting context 存在于其余 formatting context 外面,并且能够看作是 paragraph 的 context。paragraph 创立一个 inline formatting context。paragraph 会在用于文本的 <strong><a> 或者 <span> 的元素上创立 IFC。

The box model does not fully apply to items participating in an inline formatting context. In a horizontal writing mode line, horizontal padding, borders and margin will be applied to the element and push the text away left and right. However, margins above and below the element will not be applied. Vertical padding and borders will be applied but may overlap content above and below as, in the inline formatting context, the line boxes will not be pushed apart by padding and borders.

盒模型不会齐全利用于带有 IFC 的元素。在程度写模式线、程度内边距、边框和外边距会利用于元素上,并把文字推向左右。然鹅,元素的上边距和下边距不会被利用。垂直内边距和边框会被利用当可能笼罩下面或者上面的内容,因为在 IFC 中,内联盒子不会被内边距和边框所推开。

HTML

<p>Before that night—<strong>a memorable night</strong>, as it was to prove—hundreds of millions of people had watched the rising smoke-wreaths of their fires without drawing any special inspiration from the fact.”</p>

CSS

strong {
    margin: 20px;
    padding: 20px;
    border: 5px solid rebeccapurple;
}

Flex Formatting Context(FFC)和 Grid Formatting Context(GFC)

除了蕴含外部 float(因为在弹性容器或者网格容器外面不存在 float 子元素),其余都和 BFC 一样:

  1. 排除内部 float
  2. 阻止外边距折叠

总结

Formatting Context 能够看作是某块区域,这块区域规定了其上元素的布局规定。Formatting Context 次要又 4 种,BFC、IFC、FFC 和 GFC。

其中 BFC 最为重要,当一块元素随同这 BFC 时,会产生:

  1. 蕴含外部 float
  2. 排除内部 float
  3. 组织外边距折叠

FFC 和 GFC 除了子孙元素没有 float 之外,都和 BFC 一样有 2 和 3。

IFC 跟内联元素成果一样,都是垂直方向外边距有效[6]

REFERENCE

[1] https://developer.mozilla.org…

[2] https://developer.mozilla.org…

[3] https://gitee.com/gooder4j/co…

[4] https://github.com/w3c/csswg-…

[5] https://bugs.chromium.org/p/c…

[6] https://gitee.com/gooder4j/co…

退出移动版