uni-app 中 position: sticky 真机不吸顶是因为小程序及 App 端未实现该属性;H5 需满足父容器有高度、无 overflow: hidden/transform/filter、吸顶元素非 flex stretch 子项;四端兼容方案是 scroll-view + bindscroll 手动控制 fixed 定位。

uni-app 里 position: sticky 为什么在真机上完全不吸顶
不是你写错了,是微信/支付宝小程序、App 端压根没实现这个 CSS 属性。H5 虽支持,但必须同时满足:父容器有明确高度、不能设 overflow: hidden、不能含 transform 或 filter、且吸顶元素不能是 flex 子项并带 align-self: stretch。漏一条就失效,真机调试时“掉下来”是常态。
用 scroll-view + bindscroll 手动控制 fixed 最稳
这是目前唯一能同时跑通微信小程序、支付宝、App、H5 四端的方案。核心不是靠样式,而是监听滚动位置,动态切换 class 控制定位状态。
-
scroll-view必须设固定高度,比如height: calc(100vh - var(--status-bar-height)),否则bindscroll不触发 -
offsetTop(即吸顶阈值)要在onReady或nextTick后用uni.createSelectorQuery()获取,onMounted(Vue 3)里直接取可能为 0 - 吸顶后内容会“上跳”,必须加占位节点:
<view v-if="isSticky" class="placeholder" :style="{ height: headerHeight + 'px' }"></view>,不能用padding-top补高,否则滚动条跳动 -
bindscroll回调里禁止调用uni.createSelectorQuery()或getComputedStyle()—— 它们是同步阻塞操作,低端安卓机一卡一卡 - 用
requestAnimationFrame节流,只在下一帧执行一次判断,避免高频 setData
商品分类导航栏吸顶要特别注意的三件事
商品页常含 tab 切换、搜索框、筛选弹层,这些会让吸顶逻辑更脆弱。
- 吸顶区域如果含
<input>或<picker>,iOS 微信小程序中 fixed 元素会被键盘顶起,得监听keyboardheight动态调top - 分类标题若用
scroll-view横向滑动,它和外层竖向滚动容易冲突,建议把分类导航单独抽成固定定位,只监听主滚动区的scrollTop - 多个吸顶区块(如一级类目、二级类目)要分别查
offsetTop,别共用一个阈值;用id而非class查询,避免 DOM 顺序变化导致错位
别直接用 u-sticky 或 uview 的吸顶组件
它们封装了 scroll 监听,但参数稍有偏差就静默失效。比如 offsetTop 单位是 rpx,传 0 会遮挡状态栏;customNavHeight 不显式传入,在自定义导航栏下位置偏移;某些旧版 uView 改 disabled 不响应,得手动 this.$forceUpdate()。
真正复杂的地方不在“怎么吸顶”,而在“吸顶之后怎么不遮挡、不跳动、不被键盘推走、不和 tab 切换打架”。这些细节全靠手动控制,绕不开。


















