悬浮胶囊导航的实现笔记
- 日期 —
- September 10, 2026
- 标签 —
- CSS, 前端
这个站的导航栏有两种状态:顶部时是通栏白条,滚动后收缩成居中的悬浮胶囊。记录一下实现思路。
核心思路
只让一个元素负责所有变化,用 data-scrolled 属性驱动两套样式,中间靠 CSS transition 补间:
.nav-shell {
height: 4rem;
max-width: 100%;
border-radius: 0;
border-bottom: 1px solid var(--line);
transition: height .35s cubic-bezier(.22,1,.36,1), max-width .35s cubic-bezier(.22,1,.36,1);
}
.nav-shell[data-scrolled='true'] {
height: 3.75rem;
max-width: min(62.5rem, calc(100% - 2.5rem));
margin-top: 1.25rem;
border-radius: 999px;
box-shadow: 0 12px 32px -8px rgb(0 0 0 / .12);
}
JS 只有三行:监听 scroll,超过 16px 就把属性设为 true。
几个坑
height从 4rem 变 3.75rem 看似多余,但胶囊比通栏“矮一点”才有收缩感- 投影要单独过渡,不能混在
all里,否则首帧会闪 - 外层容器
pointer-events-none、内层pointer-events-auto,这样顶部与胶囊之间的空隙不会挡住点击 - 记得处理
prefers-reduced-motion,动画虽小,尊重是必须的
