CSS 原理 - Formatting Context
CSS 的排版布局主要就是看两样东西:一样就是 Box(盒模型),另一样就是 Formatting Context。盒模型具体要怎么样排序看的就是 Formatting Context 了。
Box(盒模型)
Box 相信大家都已经很熟悉了,就是 margin、border、padding、content 这四个部分。
什么是 Formatting Context
先来看一段 W3C (opens in a new tab) 规范对于 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.
A box either establishes a new independent formatting context or continues the formatting context of its containing block. The type of formatting context established by the box is determined by its inner display type.
Additionally, some types of formatting contexts interleave and co-exist.
也就是说,Formatting Context 指的是一个布局环境,处在什么布局环境里的 Box 就得按照什么环境的规则来布局。Box 里面也可以自己建立新的 Formatting Context 再继续放其他 Box。
Formatting Context 的类型
Formatting Context 大致有以下几种,其中 BFC(Block Formatting Context) 和 IFC(Inline Formatting Context) 两种对于排版来说最为重要,而除了 BFC 较为特殊之外,其余的 Formatting Context 取决于元素的 display 属性。
- Block Formatting Context (BFC)
- Inline Formatting Context (IFC)
- Flex Formatting Context (FFC)
- Grid Formatting Context (GFC)
- Ruby Formatting Context (RFC)
Independent Formatting Context
当一个 Box 建立一个独立的 Formatting Context 时(无论该格式上下文是否与其父对象类型相同,它本质上会建立一个新的、独立的布局环境:除了通过调整 Box 本身的大小,它的子对象的布局(通常)不受框外格式上下文的规则和内容的影响,反之亦然。
值得注意的是,除了 display 之外,有些属性也会建立独立的 Formatting Context,比如 float属性不为none
、position: absolute/fixed
、overflow不为visible
,这些会使元素脱离正常流的属性都会建立独立的 Formatting Context。
理解 Formatting Context
Block Formatting Context 里面有一个容器还有一个里面的子 Box 的概念。
Block Formatting Context
- block container => block-level box
而 Inline Formatting Context 里面则叫
Inline Formatting Context
- line box => inline-level box
还有其他的 Formatting Context 里面则是
Flex Formatting Context
- flex container => flex item
Gird Formatting Context
- grid container => grid items
<html>实际上就是个超大的 Box,里面装着其他 Box,并且会 establish
(建立) 一个 BFC,BFC 里面又会有 IFC,这里的 IFC 指的就是 inline-level box 里面的东西,从左到右排列(水平排列),然后 BFC 指的就是 block-level box 里面的东西已经从左到右排列,排列不下了,开始换行从上到下排列(垂直排列)。
还有我们常说的 diplay: flex 和 gird 会建立 BFC,实际上 flex 里面是 flex container => flex item,gird 里面是 grid container => grid items,不是 BFC,而 flex item 和 grid items 里面才会建立 BFC。
还有一种特殊的情况,overflow 为 visible 时,不会建立 BFC,这里涉及到了 BFC 的合并问题,这里实际上是在 block container 里面放了另一个 block container,在 CSS2.1 里面就给这种取了个名字,里面的表述是这样的:block container + block-level box
= block box
= block
,这种既是容器又是内容的就是 block,所以 block + overflow:visible 是不会建立 BFC 的特例,因为它外面有容器,所以里面就不产生了。
结语
其实 Formatting Context 的基本概念很好理解,就类似我们写作文的作文纸就是一个 BFC,里面写字,从左到右写,这里的从左到右写就是 IFC,一行写不下换另一行,这里就指的是 BFC。实际上难的点是 Formatting Context 和其他特性的一些互动,比如 margin collapse 等等。
参考
https://yachen168.github.io/article/Formatting-context.html (opens in a new tab)