左:实际比例(手机原型)。中:top 100px 放大 5 倍的"剖面图"。右:图例 + 图层开关。
~44px = --safe-area-top,material 在它下面继续延伸 10px 到 falloff。
fixed; top:0; height:6px; z-index:10100fixed; top:0——从物理顶部 y=0 开始,
一直延伸到业务内容底边。
<div class="safe-area-inset-top">,
高度 = var(--safe-area-top) ≈ 44px。透明,被状态栏 + 透出带遮。
底色通过 safe-area-class prop 控制(例如 bg-theme-container-2)。
--safe-area-top(y=44);蓝虚线 = 业务 safe area 起点(y=54)。
纯标注,不是 DOM 元素。
10px。透明,被状态栏遮。
仅在 iOS 26+ Liquid Glass 时由 wrapper 自动插入。
三种放置方式的视觉对比 + 推荐实现
广告 top: 0 被 iOS 状态栏完全盖住,
只剩底部一小条从 Liquid Glass 透出带漏出来(图中半透明部分),
视觉上等于不存在。
广告顶到 safe-area 底边,顶边压在 Liquid Glass 透出带下, 那一条 8px 被半透明层遮盖模糊(颜色发淡、有 backdrop-blur), 在 iOS 26+ 设备上形成可见的视觉瑕疵。
被 spacer 自动向下推 10px,顶边落在 Liquid Glass 透出带之下, 色块清晰;同时 placeholder 撑出对应高度,下方页面内容不会被遮。
<FixedWrapper> 包裹
项目里所有顶部 fixed 元素(NavBar、Tab、广告条、公告条…)都应该塞进同一个
<FixedWrapper>,让它统一处理 spacer / placeholder /
fixed-to-sticky 切换。
✅ FixedWrapper 自动处理 safe-area:组件内部按顺序插入
10px Liquid Glass spacer → safe-area-inset-top filler → slot 可见内容。
消费方 slot 里只写真正可见的元素;filler 底色通过
safe-area-class prop 控制(比如让它跟下方 NavBar 同色)。
<!-- baseHeight 仅传"slot 可见内容自身高度",wrapper 自动处理 spacer + safe-area filler --> <FixedWrapper :baseHeight="50" safe-area-class="bg-orange-500"> <div class="h-[50px] bg-gradient-to-r from-orange-500 to-pink-500"> <span>🎁 SALE 50% OFF</span> </div> </FixedWrapper>
<!-- 50 (NavBar) + 36 (广告) = 86,base-height 直接写 86,区间在 40~200 之间都行 --> <FixedWrapper :baseHeight="86" safe-area-class="bg-theme-card"> <NavBar /> <!-- h-[50px] --> <AdBanner /> <!-- h-[36px] --> </FixedWrapper>
baseHeight 只算可见内容(不含 safe-area filler)——因为 placeholder 镜像
wrapper 的三段高度(spacer + safe-area + slot),baseHeight 只需要给 wrapper "可见内容"
那一段。值域 40~200px,对应的 h-[Xpx] 类已通过
tailwind.config.js 的 safelist 预编译;超出区间需扩 safelist。
<!-- :sticky-transition=false 跳过 .fixed-dom / .fixed-dom-placeholder 两个 class --> <FixedWrapper :baseHeight="44" :sticky-transition="false"> <PromoBanner /> </FixedWrapper>
非 wrapper 形态的浮动元素(比如 Banner 图、悬浮订单卡)继续走
useMetaTopOffset() 拿 10/0 偏移量自己拼
top: calc(var(--safe-area-top) + ${metaHeight}px)。
safe-area-inset-top filler + slot + placeholder(placeholder 镜像前三段高度)。消费方只关心 slot 写什么y = 10 + var(--safe-area-top)(即图里业务 safe area 起点)hasLiquidGlassOffset = 0,那 10px 自动不加;这层判断包在 FixedWrapper 里,业务不用自己写 UA 判断tailwind.config.js safelist 预编译的 h-[40px]~h-[200px] 类