CSS Grid 本身不支持视差滚动,需结合 JS 监听滚动+transform 或 background-attachment: fixed(有严格生效条件)实现;Grid 仅负责静态区域划分,位移逻辑必须由运行时计算控制。

直接说结论:CSS Grid 本身不提供视差滚动能力,所谓“Grid 中实现视差滚动分栏”,本质是用 grid 布局结构 + transform: translateY() 或 background-attachment: fixed 配合滚动监听(JS)模拟效果;纯 CSS 无法让 Grid 子项根据滚动位置自动产生不同位移量。
为什么不能只靠 grid-template-rows 或 grid-auto-flow 实现视差
Grid 是静态布局系统,它按定义好的轨道分配空间,不响应滚动偏移。视差的核心是「不同层以不同速度移动」,这需要运行时计算滚动进度并应用差异化的 transform 或 background-position。试图用 grid-row-start 动态改位置、或靠 auto-fit 触发重排,都做不到像素级位移控制。
常见错误现象:
– 给 .parallax-section 设 display: grid 后发现各栏一起上下滚,毫无视差感
– 误用 background-attachment: fixed 在子元素上,结果背景被裁剪或失效(该属性只对根元素或有 transform 的祖先生效)
background-attachment: fixed 的实际生效条件
这个属性常被当作“零 JS 视差方案”,但它有硬性限制:
立即学习“前端免费学习笔记(深入)”;
- 必须作用于设置了明确
height(非auto)的块级容器 - 父容器不能有
transform、perspective、filter等创建新层叠上下文的属性,否则fixed会相对于该父容器定位,而非视口 - 在 flex/grid 容器中直接设
background-attachment: fixed通常无效,需额外加一层 wrapper 并设position: relative
示例结构:
<div class="grid-wrapper"> <div class="parallax-layer" style="background-image: url(bg1.jpg); background-attachment: fixed;"></div> <div class="content-layer">文字内容</div> </div>
其中 .grid-wrapper 需设 height: 100vh 且无 transform;.parallax-layer 要设 position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-size: cover;
用 JS 控制 Grid 子项位移更可控
当需要精确控制每栏滚动速度(比如左侧栏移动 30%,右侧栏移动 70%),必须监听 scroll 事件并更新 style.transform:
- 给每个分栏加
data-parallax-speed="0.3"这类自定义属性 - 在
requestAnimationFrame回调里读取window.scrollY,乘以 speed 得到位移值 - 对每个栏执行
element.style.transform = `translateY(${offset}px)` - 注意:Grid 容器本身不要设
overflow: hidden,否则子项位移会被裁切
关键点:Grid 只负责划分区域(如 grid-template-columns: 1fr 2fr),位移逻辑完全由 JS 承担;强行把位移逻辑塞进 CSS 自定义属性再用 @property 动画,目前兼容性极差(仅 Chrome 120+ 支持)。
折叠屏分栏场景下要防布局断裂
像 iPhone Duo 或鸿蒙折叠设备展开后变成三栏,此时视差滚动容易因容器尺寸突变导致位移错乱:
- 监听
resize和orientationchange,重置所有 parallax offset 计算基准 - 避免用
vh单位做位移值(折叠屏横竖切换时100vh会跳变),改用基于文档总高度的比例值 - 在鸿蒙 ArkUI 中,
onAreaChange回调比纯 CSS 更可靠,可结合BreakpointSystem动态开关视差效果(小屏禁用,大屏启用)
真正容易被忽略的是:视差滚动在触摸设备上默认会触发 touchmove 滞后,必须加 { passive: false } 并在回调里 preventDefault(),否则 iOS Safari 下会卡顿或失效。


















