最简滚动视差用 background-attachment: fixed 实现,需容器设明确高度(如100vh)、加 transform: translateZ(0) 修复 iOS 兼容性,避免在 sticky 或 transform 父容器内使用。

用 background-attachment: fixed 实现最简滚动视差
这是兼容性最好、开销最低的方案,适合纯背景图层(如页头 Banner),不需要 JS 干预。
关键点在于:父容器需有明确高度(不能靠内容撑开),且子元素需触发层叠上下文(否则 fixed 在部分 iOS Safari 中失效):
-
background-image必须设在具有height或min-height的块级元素上 - 加
transform: translateZ(0)或will-change: transform强制硬件加速,修复 iOS 滚动卡顿和背景错位 - 避免在
position: sticky或transform父容器内使用 —— 会截断fixed的参照系
.parallax-section {
height: 100vh;
background-image: url('bg.jpg');
background-attachment: fixed;
background-position: center;
background-size: cover;
transform: translateZ(0); /* 关键:iOS 兼容 */
}用 IntersectionObserver + transform: translateY() 做精准控制
当需要多层视差(前景/中景/背景)、或视差强度随滚动位置线性变化时,CSS fixed 不够用,必须 JS 驱动。但别用 scroll 事件 —— 容易掉帧。
IntersectionObserver 本身不监听滚动,但它能配合 getBoundingClientRect() 算出元素在视口中的相对位置,再驱动 transform:
立即学习“前端免费学习笔记(深入)”;
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
- 监听目标元素进入视口的时机,用
entry.boundingClientRect.top和window.innerHeight推算滚动比例 - 对不同图层应用不同系数:背景层用
-0.2 * scrollRatio,中景用-0.5 * scrollRatio,前景接近0 - 务必用
requestAnimationFrame批量更新样式,避免强制同步布局(offsetTop等会触发布局抖动)
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
const ratio = (window.innerHeight - entry.boundingClientRect.top) / window.innerHeight;
const bg = entry.target.querySelector('.parallax-bg');
bg.style.transform = `translateY(${ -0.3 * ratio * 100 }%)`;
});
}, { threshold: [0, 1] });
<p>observer.observe(document.querySelector('.parallax-section'));为什么 scroll 事件做视差大概率卡顿
直接监听 window.onscroll 并实时计算 scrollTop 是新手最常写的写法,但实际项目中几乎不可取。
问题不在逻辑,而在浏览器渲染管线:
- 每次
scroll触发都可能引发重排(尤其是读取offsetTop、getBoundingClientRect()时) - 即使只写
transform,若没用requestAnimationFrame节流,JS 执行会挤占主线程,导致滚动丢帧 - 移动端 WebView(如微信内置浏览器)对高频
scroll更敏感,容易出现“跳变”而非平滑视差
替代方案不是“不用 JS”,而是换触发源:IntersectionObserver + raf 组合可把 FPS 稳定在 60,且内存占用低。
移动端适配最容易被忽略的三个点
视差效果在桌面端跑得顺,一到手机就错位、卡死、甚至白屏 —— 大多栽在这几个细节上:
- iOS Safari 对
background-attachment: fixed支持极差,会退化为scroll;必须加transform: translateZ(0)或用 JS 方案兜底 - 安卓部分低端机(尤其 Chrome 80 以下)不支持
IntersectionObserver,需用@supports检测并 fallback 到节流scroll - 视口缩放(双指 pinch-zoom)会破坏
vh单位和getBoundingClientRect()的精度,建议禁用缩放:<meta name="viewport" content="width=device-width, user-scalable=no">
复杂点从来不在“怎么做出效果”,而在于“怎么让效果不崩在各种边缘场景里”。滚动视差尤其如此 —— 它天然依赖渲染时序与设备能力,少一个兼容补丁,用户看到的就是撕裂或卡死。

















