position: sticky 实现吸顶导航需设 top 值且父容器禁用 overflow: hidden 或 transform;兼容性差时用 JS 监听 scroll 切换 fixed 类,并通过 padding-top 避免遮挡。

用 position: sticky 实现最简吸顶导航
直接加 position: sticky 就能生效,但必须配合 top 值,且父容器不能有 overflow: hidden 或 transform 等触发新层叠上下文的属性,否则会失效。
常见写法:
nav {
position: sticky;
top: 0;
z-index: 100;
background: white;
}
-
top: 0表示贴着视口顶部吸住;设为top: 20px则离顶部 20px 吸住 - 父元素(比如
<header>)若设置了overflow: hidden,sticky会退化为relative - 如果导航本身在
transform容器内(如轮播图 wrapper),也大概率失效
兼容性差时 fallback 到 position: fixed
IE 完全不支持 sticky,Safari 旧版本也有 bug。需要 JS 监听滚动并手动切状态。
核心逻辑:判断导航元素的 offsetTop 是否小于 window.scrollY,是则加 fixed 类。
立即学习“前端免费学习笔记(深入)”;
const nav = document.querySelector('nav');
const navTop = nav.offsetTop;
window.addEventListener('scroll', () => {
if (window.scrollY >= navTop) {
nav.classList.add('fixed-top');
} else {
nav.classList.remove('fixed-top');
}
});
- CSS 中需预定义
.fixed-top { position: fixed; top: 0; width: 100%; } - 注意 fixed 后会脱离文档流,原位置留空,建议给 body 加一个等高占位
padding-top - 滚动事件高频触发,可加
requestAnimationFrame节流,但简单场景不加也行
吸顶后内容被遮挡?检查 z-index 和布局塌陷
吸顶导航盖住下面内容,通常不是 z-index 不够高,而是下面内容没“让出空间”。
- 用
sticky时,元素仍在文档流中,不会导致塌陷,但可能被其他z-index更高的元素覆盖 - 用
fixed时,必须手动补偿:给紧接其后的元素加margin-top,或给body加padding-top -
z-index只对定位元素(relative/absolute/fixed/sticky)有效,普通块级元素无效
移动端滚动卡顿?避免在 scroll 里强制同步重排
JS fallback 方案中,读取 nav.offsetTop 或 getBoundingClientRect() 会触发重排,频繁滚动时明显卡顿。
- 把
navTop提到 scroll 外部缓存,不要每次读offsetTop - 避免在 scroll 回调里操作 DOM 样式(如直接改
style.top),统一用 class 切换 - 真要高性能,可用 IntersectionObserver 替代 scroll 监听,但需注意兼容性(iOS Safari 12.2+ 支持)
overflow 或 transform 上,先检查这两项,比调 z-index 有用得多。


















