纯css变量无法驱动视差滚动,必须由javascript监听scroll事件并动态设置:root变量,css仅能通过calc()加法结合硬编码系数消费变量实现背景位移,多层视差需独立变量与系数,且须用requestanimationframe保帧率。

纯 CSS 变量无法驱动视差滚动——scroll 事件、window.scrollY 和滚动位移计算必须由 JavaScript 完成,CSS 变量只能作为“传值管道”,不能监听或响应滚动。
为什么 :root 变量 + background-position 不会自动更新
CSS 自定义属性(--parallax-offset)是静态的,除非 JS 显式调用 document.documentElement.style.setProperty(),否则它不会随滚动变化。写成 background-position: center calc(var(--parallax-offset) * 0.4) 是无效语法——calc() 里不支持变量参与乘法运算,且浏览器不会把 --parallax-offset 当作实时数值去重算。
-
calc(var(--x) * 0.5)在所有浏览器中都会解析失败,报invalid property value - 即使绕过语法限制(比如预设多个断点类),也无法实现连续平滑位移
-
@scroll-timeline虽然纯 CSS,但它不读取自定义变量,而是直接绑定滚动进度到动画帧
JS 设置变量 + CSS 使用的可行链路
可以借助 JS 更新变量,再让 CSS 消费该变量,但仅限于 background-position 的 y 偏移(transform 不推荐用变量驱动,性能差):
- HTML 中确保目标元素有
style="background-attachment: scroll",禁用fixed避免移动端失效 - JS 里用
requestAnimationFrame节流,每次滚动时执行:document.documentElement.style.setProperty('--scroll-y', `${window.scrollY}px`) - CSS 中写:
.parallax-bg { background-position: center calc(50% + var(--scroll-y, 0px) * 0.3); }—— 注意:这里calc()实际只做加法,乘法系数 0.3 必须硬编码,不能是另一个变量 - 必须配
background-size: cover和background-repeat: no-repeat,否则偏移后边缘露白
多层视差必须各自独立控制变量
不同速度的背景层不能共用一个 --scroll-y,否则失去“视差”意义。你需要为每层设专属变量:
-
--scroll-y-bg1→ 速度系数 0.2 -
--scroll-y-bg2→ 速度系数 0.5 -
--scroll-y-bg3→ 速度系数 0.8(慎用,易晕) - JS 中分别设置:
el1.style.setProperty('--scroll-y-bg1', `${scrollY * 0.2}px`) - CSS 中对应写:
.bg1 { background-position: center calc(50% + var(--scroll-y-bg1, 0px)); }
真正难的不是传值,而是保持滚动位移与视觉反馈的帧率一致——只要 JS 里没用 requestAnimationFrame,或者 CSS 中用了 top/margin-top 触发 layout,哪怕变量传对了,也会在 iOS 上卡顿、跳变。变量只是胶水,底层滚动响应逻辑一点都不能松。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











