ssr 时 grid-template-areas 可直出确定结构,不依赖 hydration;其字符串和行列定义均为静态声明,服务端可直接求值写入 html,避免因变量未收敛导致解析失败和 cls。

SSR 时 grid-template-areas 能直出确定结构,不依赖 hydration
服务端渲染(SSR)阶段没有 JS 执行环境,也无法测量 DOM 尺寸。CSS Grid 的 grid-template-areas、grid-template-columns、grid-template-rows 都是静态字符串或数值声明,Node 环境可直接求值并写入 HTML,浏览器拿到的初始 HTML 已含完整网格定义。
常见错误现象:grid-template-areas: "${headerArea} ${mainArea}" 中变量未在服务端收敛 → 输出空字符串或非法值 → 浏览器解析失败,所有子项塌缩到左上角,hydration 后重排触发 CLS。
- ✅ 推荐写法:
grid-template-areas: "header main" "footer footer"—— 字符串常量,SSR 可直出 - ❌ 危险写法:
grid-template-columns: ${isWide ? "200px 1fr" : "1fr"}—— 若isWide未在服务端正确计算,会输出无效 CSS - 所有参与 Grid 计算的 class 名、CSS 自定义属性、内联
style必须在 SSR 时已收敛,否则 hydration 阶段 layout shift 不可避免
Grid 容器不靠内容撑高,天然抑制 CLS 主要诱因
CLS(累积布局偏移)最常见来源,就是容器高度随图片加载、字体渲染、异步内容插入而突然增长。Flexbox 或普通块级容器常依赖子项内容撑开高度;Grid 则允许你用 grid-template-rows: 60px auto 50px 提前锁定主轴空间分配,即使子项尚未加载,容器高度也不会跳变。
- auto 行仍可能受内容影响,关键区域慎用;优先写
minmax(200px, 1fr)或固定值 - 若必须响应内容高度(如富文本),给该 Grid 项目加
contain: layout,隔离内部重排不扩散 - 避免 SSR 模板里留空 Grid 容器(如
<div class="grid"></div>),应至少占位一个骨架节点,防止 hydration 后 DOM 插入引发位移
Grid 子项定位不依赖 JS,消除 hydration 时序差
很多 SSR 布局偏移实际来自客户端 JS 在 hydration 后才去动态设置 style.gridColumn 或调用 getBoundingClientRect() 计算位置。Grid 的 grid-column、grid-row、grid-area 全部是纯 CSS 声明,浏览器在解析 HTML/CSS 阶段就完成定位,无需等待 JS 执行。
- 浮动(
float)在 Grid 容器中被规范废弃,float: left会被静默忽略 —— 不是兼容性问题,是行为不合法 -
justify-self、align-self可直接控制单个项目对齐,无需 wrapper +margin-left: auto等 hack - 设计稿中的 Figma 布局图可直接转成
grid-template-areas字符串,前后端对齐成本低,也减少运行时逻辑介入
对比 Flexbox:为什么它在 SSR 中更容易出偏移
Flexbox 布局常隐式依赖运行时测量:比如 flex: 1 需要父容器有明确高度才能生效;flex-wrap: wrap 的换行点取决于子项实际宽度;align-items: stretch 会拉伸子项高度,但 SSR 时无法预知子项内容尺寸。这些行为在服务端无法模拟,必然留空或估算偏差,导致 hydration 后强制重排。
- Flexbox 容器若只写
display: flex; flex-direction: column,某张卡片图片加载完成瞬间增高,下方内容立刻被推挤 —— Grid 则可通过grid-template-rows锁定轨道高度 - Flexbox 的
gap虽已支持,但老版本 fallback 常靠margin,而 margin 在 SSR 和 hydration 后可能因盒模型计算差异导致错位 - Flexbox 的响应式换行(如
flex-wrap)在 iOS Safari 和安卓 WebView 中解析偏差明显;Grid 的auto-fit + minmax()行为可预测、可复现
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











