应统一使用 rgba() 设置背景色起始值与结束值,将 transition 写在基础 .navbar 规则中,并为 .navbar-collapse 单独控制背景类;否则 background-color 过渡失效或移动端不生效。

直接用 classList.toggle() 切换预设类,配合 transition: background-color 实现平滑变色,别在 scroll 回调里反复写 element.style.backgroundColor —— 那样既没过渡、又难维护,Safari 下还容易闪白。
为什么 background-color 过渡不生效
最常见原因是起始值用了 transparent,结束值却是 rgba() 或十六进制色。浏览器无法在关键字和颜色值之间插值。必须统一用 rgba():
- 默认状态设为
background-color: rgba(255, 255, 255, 0) - 滚动后切到
background-color: rgba(255, 255, 255, 0.95) -
transition: background-color 0.3s ease必须写在默认的.navbar规则里,不能只写在.navbar-scrolled中 - 如果用了
background-image: linear-gradient(),务必加background-image: none,否则它会盖住你设的背景色
滚动阈值该用 scrollY 还是 getBoundingClientRect().top
用 window.scrollY > 50 看似简单,但一旦页面有首屏大图、响应式 padding 变化或 sticky fallback,这个固定值就失效。更稳的是监听导航栏自身位置:
- 取
document.querySelector('.navbar').getBoundingClientRect().top - 当它 ≤ 1(留缓冲)时触发变色,比严格等于 0 更适配移动端 Safari
- 首次加载后需手动调用一次判断逻辑,否则刷新后状态可能错乱
- 别在滚动回调里反复调用
getBoundingClientRect()—— 提前缓存元素引用,只在requestAnimationFrame里读一次
移动端 .navbar-collapse 背景为啥还是透明
.navbar-collapse 是独立容器,不会继承 .navbar 的背景色或类名。你在 .navbar 上加了 .scrolled,但折叠菜单展开后仍透出底下内容:
- HTML 中显式给
<div class="navbar-collapse">加bg-white(或对应主题类) - JS 里同步控制:用
document.querySelector('.navbar-collapse').classList.toggle('bg-white', scrolled) - 别依赖
!important强刷样式,容易和深色模式、响应式类冲突 - 如果用了
data-bs-theme="dark",记得为.scrolled单独定义深色背景值,比如rgba(33, 37, 41, 0.95)
真正卡点不在 JS 写法,而在 CSS 起始值类型是否统一、transition 是否落在基础规则中、以及 .navbar-collapse 是否被遗忘——这三处一漏,滚动变色就变成“啪”一下跳过去,或者只在桌面端有效。


















