浏览器渲染管线
3. 布局阶段 (Layout)
具体流程
3.1 构建布局树(Layout Tree)
- 从渲染树(包含样式信息的 DOM 树)出发,过滤掉不需要渲染的节点:
- 移除
display: none
的元素 - 保留
visibility: hidden
的元素(占据空间但不绘制)
- 移除
- 生成仅包含可见元素的布局树
- 布局树节点包含:
- 几何属性(位置、大小)
- 父元素与子元素的层级关系
3.2 递归计算几何信息
从根节点(<html>
)递归遍历布局树,计算每个元素的盒模型和定位信息:
确定包含块(Containing Block):
定位类型 包含块规则 边界类型 static
/relative
最近块级祖先的内容盒
(块容器或格式化上下文祖先)content box absolute
最近非 static
祖先的内边距盒
(无则使用初始包含块)padding box fixed
视口
或设置以下属性的祖先:transform
/perspective
/filter
/contain: paint
padding box sticky
最近滚动祖先的内容盒
(无则使用视口)content box 关键概念:包含块是元素尺寸计算(
width/height/padding/margin
)和位置计算(top/right/bottom/left
)的参考基准。
依据:Definition of "containing block"处理盒模型:
- 根据
width/height
计算内容区域 - 处理
padding
/border
/margin
值 - 百分比值:基于包含块的对应尺寸计算
- auto 值:根据布局模式自动计算
- 根据
处理定位类型:
- 正常流:
- 块级元素:垂直堆叠,宽度填满包含块
- 行内元素:水平排列(IFC 上下文)
- 计算行高(
line-height
) - 基线对齐(
vertical-align
) - 文本对齐(
text-align
) - 行盒(Line Box)高度计算
- 计算行高(
- 浮动:
- 计算
float: left/right
位置 - 处理文字环绕效果
- 计算
- 绝对定位:
- 根据包含块计算精确位置
- 完全脱离文档流
- 固定定位:
- 相对于视口定位
- 特例:祖先设
transform
时锁定在该祖先
- 粘性定位:
- 在滚动容器内切换相对/固定定位
- 在滚动容器内切换相对/固定定位
- 正常流:
文字排版:
- 在行内格式化上下文(IFC)中计算:
- 文本换行位置
- 行盒高度(由行内最高元素决定)
- 基线对齐(
vertical-align
)
- 在行内格式化上下文(IFC)中计算:
3.3 处理复杂布局模式
Flexbox 布局:
- 计算主轴/交叉轴尺寸
- 分配剩余空间(
flex-grow/shrink
) - 处理项目对齐(
justify-content
/align-items
)
Grid 布局:
- 计算网格轨道(行/列)尺寸
- 放置网格项目到指定区域
- 处理网格间隙(
gap
)
3.4 存储布局结果
- 记录计算得到的几何信息:
- 位置坐标(x, y)
- 尺寸(width, height)
- 盒模型各部分值(content/padding/border/margin)
- 建立空间关系:
- 元素间相对位置
- 物理重叠情况(为分层阶段准备)