组件概览
吸顶(position: sticky)是把元素在滚动过程中「钉」在某个位置的能力。与固定定位(position: fixed)不同,吸顶元素仍然保留在文档流中,占据原有的空间,只有当它即将滚出视口时才会被钉住,并且在离开父容器时自动释放。因此它天然适合工具栏、表头、目录、分组标题这类需要「跟随阅读位置」的元素。
这些规则的关键在于,吸顶元素的判定依赖最近的滚动容器。如果祖先元素设置了 overflow: hidden,浏览器会把该祖先视为滚动容器,而它自身并不滚动,于是吸顶效果会完全失效。排查「吸顶不起作用」这类问题时,第一步永远是向上查找是否存在 overflow 非 visible 的祖先。
滚动行为
组件库把顶栏高度统一约定为 64px,并在全局样式中设置了 88px 的滚动留白(scroll-padding-top)。吸顶元素的偏移量取 72px —— 即顶栏 64px 加上 8px 的呼吸空间。这样当页面通过锚点跳转定位到某个标题时,标题不会紧贴顶栏,也不会被吸顶工具栏盖住。
当同一区域出现两层吸顶时,第二层的偏移量需要累加:例如吸顶工具栏 72px,其下方的吸顶表头需要设置为 72px + 工具栏高度。组件库的表格组件默认不做表头吸顶,以避免与工具栏叠加产生视觉冲突;确有需要时,请显式传入偏移量。
.sticky-top {
position: sticky;
top: 72px; /* 顶栏 64px + 8px 呼吸空间 */
z-index: 50; /* 低于顶栏 1000,高于内容层 */
}
祖先元素不可裁剪
若吸顶容器被放在 overflow: hidden / auto / scroll 的父级内,且该父级自身不滚动,吸顶会失效。请改用 overflow: visible 的容器,或把滚动容器本身作为吸顶参照。
偏移量计算
偏移量并不是一个可以随意填写的数字,它必须与固定顶栏的实际高度保持一致。当顶栏在小屏下变矮、或当页面进入全屏模式导致顶栏隐藏时,偏移量都需要重新计算,否则吸顶元素与顶栏之间会出现空隙或者重叠。
顶栏高度64 px
呼吸空间8 px
吸顶偏移72 px
锚点留白88 px
层级关系内容 1 → 吸顶 50 → 顶栏 1000 → 弹窗 2000
移动端处理
在窄屏下,侧栏以抽屉形式出现,主内容区不再有 264px 的左偏移。此时吸顶工具栏需要允许横向滚动而不是换行,否则工具栏会因为内容折行而占用过多高度,压缩正文的可读区域。组件库的做法是:在窄屏下给工具栏加 overflow-x: auto 与 white-space: nowrap,并隐藏非关键操作按钮。
另一个常见问题是 iOS Safari 在滚动惯性过程中不会实时更新 sticky 的位置,导致吸顶元素出现轻微抖动。这类抖动无法通过 CSS 完全消除,建议不要在吸顶元素上叠加复杂的模糊与阴影动画。
性能建议
position: sticky 由合成线程处理,本身几乎不产生布局抖动,比通过滚动事件动态切换 position: fixed 的方案便宜得多。如果确实需要监听滚动来做联动(例如根据滚动方向隐藏/显示工具栏),务必使用 passive 监听并在事件回调中使用 requestAnimationFrame 节流。
对于包含大量子元素的吸顶容器,可以为它单独提升为合成层(will-change: transform),但这会带来额外的显存开销。组件库默认不添加该属性,只有在实测出现掉帧时才建议开启。
无障碍
吸顶元素在键盘导航时不会自动聚焦,因此不要在吸顶容器内放置必要的操作而不提供其他入口。当用户放大页面到 200% 时,吸顶区域可能占据超过一半的视口高度,请确保吸顶内容高度不超过视口高度的 40%。
目录中的当前章节需要同时用颜色和字重两种方式表达,不要只依赖颜色。组件库使用左侧 3px 竖条 + 字重加粗双重标识,色觉障碍用户同样可以辨识。