position: sticky 在 uni-app 中基本不可用——小程序不支持,H5 条件严苛,App 端兼容差;唯一稳定跨端方案是 scroll-view + @scroll 监听 + 动态 fixed 控制。

直接说结论:position: sticky 在 uni-app 里基本不能用——微信/支付宝小程序不支持,H5 需严苛条件,App 端内核混乱,真机一跑就“掉下来”。唯一稳的跨端方案是 scroll-view + @scroll 监听 + 动态 fixed 控制。
为什么 position: sticky 在 uni-app 里大概率失效
不是你 CSS 写错了,是平台压根没实现:
- 微信/支付宝/百度小程序:渲染层完全不识别
sticky,加-webkit-sticky也没用 - H5:必须同时满足——父容器不能有
transform/overflow: hidden,吸顶元素不能是flex子项且align-self: stretch,还必须显式写top: 0 - App(尤其 iOS):老版 UIWebView 或碎片化 WKWebView 对
sticky支持极差,滚动中易跳动、错位甚至卡死
scroll-view + @scroll 实现吸顶的关键实操点
核心逻辑是监听滚动位置,手动切换定位状态。但几个细节不处理,立刻翻车:
- 必须给
scroll-view设置固定高度,例如height: calc(100vh - var(--status-bar-height));不设高度,@scroll根本不触发 -
offsetTop必须在onReady或this.$nextTick后用uni.createSelectorQuery()获取;onMounted中 DOM 常未渲染完,取值为0,吸顶阈值永远不满足 - 吸顶后内容会“上跳”,必须加占位节点:
<view v-if="isSticky" class="placeholder" :style="{ height: headerHeight + 'px' }"></view>;别用padding-top补高,会导致滚动条突变跳动 -
headerHeight要用uni.upx2px(80)转成 px,因为scrollTop单位恒为 px,混用 rpx 会偏移
高频 @scroll 导致卡顿怎么破
低端安卓机上,@scroll 每秒可能触发上百次,每次查 DOM + setData + 样式切换,必然掉帧:
- 必须用
requestAnimationFrame节流,确保一帧只执行一次判断逻辑 - 只在
scrollTop真正跨越阈值时才更新isSticky,比如从变为 <code>>= headerHeight,避免无意义重绘 - 绝对不要在
@scroll回调里反复调用uni.createSelectorQuery()或getComputedStyle()——它们是同步阻塞操作,极易丢帧
吸顶区域含 input 或 picker 时的坑
iOS 微信小程序中,fixed 元素遇到键盘弹起会被顶出视口:
- 需监听
keyboardheight变化,动态调整top值,例如top: keyboardHeight ? `calc(${keyboardHeight}px)` : '0' - 若吸顶区包含
picker-view,不能直接套sticky;得用view包裹并设pointer-events: none,再单独给picker-view加pointer-events: auto,否则点不动 - 占位节点高度必须严格等于吸顶元素渲染后的实际高度(含边框、内边距),不能靠预估或 CSS 计算,否则锚点跳转偏移
最常被忽略的是:吸顶栏高度和占位节点高度必须完全一致,且这个值必须是运行时真实像素值——写死在 JS 里、用 rpx 直接赋值、或忽略状态栏补偿,都会导致吸顶后内容错位、滚动锚点漂移。


















