
本文详解如何为滚动时隐藏/显示的固定页眉添加一致的 0.5 秒 ease-in-out 过渡动画,解决“消失瞬间无动画”这一常见问题,核心在于保留 CSS 过渡属性不被类切换中断。
本文详解如何为滚动时隐藏/显示的固定页眉添加一致的 0.5 秒 `ease-in-out` 过渡动画,解决“消失瞬间无动画”这一常见问题,核心在于保留 css 过渡属性不被类切换中断。
在现代网页中,滚动时自动隐藏/显示页眉(sticky header)是提升用户体验的常用交互模式。但许多开发者会遇到一个典型问题:页眉向上滚动时能平滑滑出(transition: top 0.5s ease-in-out 生效),而向下滚动隐藏时却“啪”地瞬时消失——这是因为原逻辑中通过 removeClass('header__top') 移除了包含 transition 声明的类,导致过渡样式丢失,浏览器无法触发过渡动画。
根本原因:CSS 过渡(transition)必须作用于同一元素在状态变化前后均具备该过渡声明的场景。当 header__top 类(含 transition)被立即移除、nav_up 类(仅含 top: -120px)被立即添加时,元素在切换瞬间既无 transition 也无有效的 top 起始值,动画自然失效。
✅ 正确解法:延迟移除过渡源类,确保过渡链完整
关键不是“先加后删”,而是先添加目标类(触发 top 变化),再在下一帧移除源类,使 transition 始终生效。jQuery 提供了 .addClass(className, callback) 的便捷写法(注意:此为 jQuery 3.4+ 支持的语法;若使用旧版 jQuery,需改用 setTimeout 或 requestAnimationFrame)。以下是优化后的核心逻辑:
if (st > lastScrollTop && st > navbarHeight) {
// ✅ 正确顺序:先添加 nav_up(触发动画起点),再移除 header__top(保留在动画期间)
$('header').addClass('nav_up', function() {
$(this).removeClass('header__top');
});
$('label').removeClass('menu__btn').addClass('nav_up');
} else {
// 向上滚动:先移除 nav_up,再添加 header__top(同样保证 transition 存在)
$('header').removeClass('nav_up').addClass('header__top');
$('label').removeClass('nav_up').addClass('menu__btn');
}同时,确保 CSS 中 transition 声明仅保留在 header__top 类中(而非 nav_up),因为 nav_up 是纯状态类,不应干扰过渡逻辑:
.header__top {
width: 100%;
height: 120px;
background-color: #000;
position: fixed;
top: 0;
z-index: 5;
transition: top 0.5s ease-in-out; /* ✅ 过渡只在此处定义 */
}
.nav_up {
top: -120px; /* ❌ 不要在此处写 transition */
}⚠️ 重要注意事项:
- 若使用 jQuery
- 确保 nav_up 的 top 值严格等于页眉高度的负值(如 -120px),否则位移量不匹配将导致动画错位;
- 滚动节流建议升级为 requestIdleCallback 或现代 IntersectionObserver + scroll passive 事件,以提升性能;
- 移动端需额外处理 touchmove 事件,并考虑 position: sticky 的兼容性替代方案。
总结:页眉滚动过渡的一致性,本质是 CSS 动画生命周期管理问题。只要确保 transition 属性在状态变化全程有效存在,并通过 DOM 更新时机控制类切换节奏,即可实现上下滚动均平滑的视觉体验。无需引入额外库,纯 CSS + 合理 JS 时序即可优雅解决。










