必须用 javascript 监听 scroll 事件配合 opacity 和 transition 实现渐隐,因 css 无法感知滚动位置;正确做法是用 requestanimationframe 动态计算 opacity 并设置 style.opacity,同时声明 transition 确保动画平滑。

不能只靠 CSS 实现——必须用 JavaScript 监听 scroll 事件,配合 opacity 和 transition 控制渐隐。纯 CSS 没有滚动位置感知能力,:hover、媒体查询、伪类都无济于事。
为什么 position: fixed 元素无法纯 CSS 渐隐
CSS 本身不提供基于滚动距离的条件逻辑。所谓“滚动到某高度后渐隐”,本质是:当 window.scrollY > N 时,逐步降低透明度。这个判断只能由 JS 做,CSS 只负责执行动画。
常见误操作包括:
- 给
fixed元素写@keyframes+animation:只会循环播放,不响应滚动 - 用
scroll-behavior: smooth试图触发状态:它只控制滚动过程,不暴露位置 - 依赖
intersection-observer监听视口进入:它适合“显隐切换”,不适合“连续渐变”
正确做法:监听 scroll 并动态设置 opacity
核心是把滚动偏移量映射为 0~1 的 opacity 值,再用 CSS 过渡平滑呈现。关键点不是“加 class”,而是“实时设 style.opacity”。
实操建议:
- 用
requestAnimationFrame替代直接在window.onscroll里计算,避免丢帧 - 定义渐隐区间,比如从
scrollY = 100开始淡出,到scrollY = 300完全透明,公式为:opacity = Math.max(0, 1 - (scrollY - 100) / 200) - CSS 中必须声明
transition: opacity 0.3s ease,否则 JS 改值也不会有动画 - 避免用
visibility: hidden或display: none:它们会中断过渡,且display触发重排
移动端和 iOS 的隐藏陷阱
iOS Safari 在键盘弹出、地址栏收起时,window.innerHeight 和 visualViewport.height 会突变,但 window.scrollY 不变,导致 opacity 计算错乱——按钮可能突然消失或卡在半透明状态。
应对方式:
- 不要只依赖
window.scrollY,可结合document.documentElement.scrollTop(兼容旧版)做 fallback - 节流不是可选项,是必选项:用
let ticking = false+requestAnimationFrame控制更新频率 - 渐隐阈值别设太低(如
> 50px),首屏加载时用户还没开始滚动,就看到导航变淡,体验割裂
真正难的不是写那几行 JS,而是让 opacity 变化节奏匹配人眼感知——太快像闪退,太慢像卡顿;而滚动事件在不同设备上触发密度差异极大,这点容易被忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











