我们之前讲的:
文档流 → 格式化上下文 → 包含块 → 层叠上下文
这几层都是“逻辑层面的排版规则”,属于 Layout(布局阶段)。
而在前面我们在讲fixed和transform时遇到了其他的概念:图层、合成层(Layer / Compositing Layer)
这些其实属于 Rendering(渲染阶段)。
接下来我会从“浏览器的渲染流水线”出发,把整个 CSS 世界从上到下铺开。
从排版到渲染:浏览器做了什么?
当浏览器渲染一个页面时,它的完整流程是这样的:
HTML → DOM 树 → CSSOM 树
↓
Render Tree(渲染树)
↓
Layout(排版/布局)
↓
Paint(绘制)
↓
Compositing(合成)
可以粗分为三大阶段:
| 阶段 | 作用 | 典型CSS影响 |
|---|---|---|
| 布局阶段 (Layout) | 决定每个元素“在哪里” | display、 position、 float、 width/height |
| 绘制阶段 (Paint) | 决定每个元素“长什么样” | background、 border、 box-shadow、 color |
| 合成阶段 (Compositing) | 决定“怎么叠加在一起” | z-index、 opacity、 transform、 filter |
在绘制阶段出现的各种“图层”
当渲染树经过布局后,每个盒子都会被“画”出来。
但画的过程不是简单一张图,而是分层绘制的。
我们可以把每个文档理解为一个“多层画布”的叠加系统:
1. 背景层(background layer)
- 绘制背景色、背景图像。
- 比如
<body>的背景色、background-image等。 - 不含内容,只是一层底色。
2. 边框层(border layer)
- 绘制边框与圆角等视觉修饰。
3. 内容层(content layer)
- 绘制文字、图片、内联元素等内容。
color、text-shadow都属于这里。
4. 装饰层(decoration layer)
- 绘制
outline、box-shadow、伪元素(::before、::after)等。
这些图层只是“视觉绘制层(Paint Layer)”,
还处在 CPU 的“画图”阶段。
此时每个盒子都在一张统一的大画布上按顺序绘制。
为什么还需要“合成层(Compositing Layer)”?
问题在于:
如果页面中某个元素不断变化(如动画、滚动、透明度、变形),
而浏览器每次都要重新绘制整张画布,会非常耗性能。
于是出现了“合成层(compositing layer)”机制:
浏览器会将某些元素单独提取到** GPU 图层**上,
它们可以独立绘制、移动、透明、旋转,而不影响其它部分。
这种 GPU 图层称为:
合成层(compositing layer),
或更通俗的名字:渲染层(rendering layer)。
会触发合成层的典型条件
浏览器会在以下几种情况下“主动”或“被迫”创建新的合成层:
| 触发方式 | 说明 |
|---|---|
transform | 元素进行了空间变换,浏览器需要独立渲染它 |
opacity < 1 | 半透明元素必须单独合成 |
position: fixed | 相对视口固定,需要独立图层 |
will-change | 开发者显式告诉浏览器未来要频繁改变的属性 |
filter/ perspective/ mix-blend-mode | 复杂视觉效果必须独立 GPU 处理 |
video/ canvas/ iframe | 天生独立的渲染内容 |
浏览器合成层的分层体系
最终,浏览器内部的层级可以简化成这样一棵树:
渲染树(Render Tree)
│
├── 普通绘制层(Paint Layer)
│ ├── 背景层(background)
│ ├── 边框层(border)
│ ├── 内容层(content)
│ └── 装饰层(decoration)
│
└── 合成层(Compositing Layer)
├── GPU 独立图层(transform、opacity、video)
└── 层叠上下文(Stacking Context)作为逻辑边界
可以这么理解它们的层级关系:
| 层级 | 所属阶段 | 作用 | 举例 |
|---|---|---|---|
| 文档流 (Document Flow) | 布局阶段 | 元素排版关系 | 块/内联排版 |
| 格式化上下文 (BFC/IFC) | 布局阶段 | 内部排版规则 | float、inline 排列 |
| 包含块 (Containing Block) | 坐标阶段 | 定位参照 | relative、absolute |
| 层叠上下文 (Stacking Context) | 绘制阶段 | 控制 z 轴顺序 | z-index |
| 绘制层 (Paint Layer) | 绘制阶段 | 渲染视觉样式 | 背景、文字、阴影 |
| 合成层 (Compositing Layer) | 合成阶段 | GPU 独立合成 | transform、opacity |
文档流->合成层
1️⃣ 文档流(Document Flow)—— 结构层
↓
2️⃣ 格式化上下文(Formatting Context)—— 排版层
↓
3️⃣ 包含块(Containing Block)—— 坐标层
↓
4️⃣ 层叠上下文(Stacking Context)—— Z 轴逻辑层
↓
5️⃣ 绘制层(Paint Layer)—— 视觉层
↓
6️⃣ 合成层(Compositing Layer)—— GPU 渲染层
它们从上到下的关系就像:
结构 → 排版 → 定位 → 叠放 → 绘制 → 合成