日期:2026-09-12
范围:miniprogram中navigationStyle: custom的页面
状态:待用户审阅后进入实现计划
体验版中,从工作台进入地磅「仪表盘」等自定义导航页时,业务顶部栏(返回、标题、右侧用户名/操作)与微信小程序原生顶栏(状态栏 + 右上角胶囊「··· / 关闭」)重叠,尤其右侧关闭按钮区域会挡住业务内容。
根因:
padding(如 .db-header { padding: 12px 16px }),未计入 statusBarHeight。utils/safeArea.js、components/app-safe-header.vue 与 CSS 变量约定(--sq-safe-top 等),但:
applySafeAreaCssVars 仅写入 H5 的 document.documentElement,微信小程序端不生效;app-safe-header 未被任何页面引用;.db-header、报销 .topbar、壳层 .mp-header 未统一消费同一套量纲。用户确认采用 方案 B:顶部加高并对齐胶囊垂直中心,右侧永久预留胶囊宽度,业务可点按钮不得放入胶囊区。
safeArea 基建,统一样式入口,避免每页手写高度。safe-area-inset-bottom(除非顺带发现明显缺陷且与本次无关则不做)。沿用并落实 miniprogram/utils/safeArea.js 的计算(uni.getSystemInfoSync + uni.getMenuButtonBoundingClientRect):
| 变量 | 含义 | 典型算法 |
|---|---|---|
--sq-safe-top |
状态栏高度 | statusBarHeight |
--sq-nav-height |
导航内容行高(与胶囊垂直居中) | (capsule.top - statusBarHeight) * 2 + capsule.height,下限 44 |
--sq-header-height |
顶栏总高 | safe-top + nav-height |
--sq-capsule-right-safe |
右侧预留宽 | capsule.width + (windowWidth - capsule.right) + 水平余量,无胶囊时为 0 |
启动时 App.onLaunch 已调用 initGlobalSafeArea();实现时须保证指标写入 小程序可消费的样式(见 §5),不能仅依赖 H5 document。
结构:
┌─────────────────────────────────────────────┐
│ 状态栏占位 (--sq-safe-top) │
├──────────┬──────────────────┬───────────────┤
│ 返回+标题 │ 次要信息(可选) │ 胶囊右侧空白 │
│ │ │ (不可放按钮) │
└──────────┴──────────────────┴───────────────┘
←────────── --sq-nav-height ───────────────→
约束:
--sq-header-height;内容行垂直居中对齐胶囊。auto | minmax(0,1fr) | var(--sq-capsule-right-safe)。.mp-header)padding-top: calc(var(--sq-safe-top) + 内容上边距)(替换仅 env(safe-area-inset-top) 或写死像素)。padding-right: calc(水平内边距 + var(--sq-capsule-right-safe)),保证副文案/用户信息不进入胶囊区。--sq-capsule-right-safe 区域(工作台现有右侧用户栈需按此收紧)。采用 「SCSS 统一吃变量 + 顶栏根节点内联注入」,不强制先改完所有页面 DOM:
getGlobalSafeArea() 返回四变量的 style 对象(px 字符串)。.db-header / .bx-page .topbar / .mp-header(及必要变体)在 SCSS 中改用 --sq-*;各页顶栏根节点绑定 :style="safeAreaStyle"(或等价)。app-safe-header:补齐样式与插槽后,新页优先使用;存量地磅/报销可先改 SCSS + 内联变量,不必一次性替换 DOM。applySafeAreaCssVars:保留 H5 写入 document;微信端以顶栏内联为准(不依赖 page 全局 CSS 变量穿透)。禁止:仅增大固定 padding-top、不预留右侧(已否决的方案 C)。
| 样式/组件 | 路径 | 动作 |
|---|---|---|
| safeArea 工具 | miniprogram/utils/safeArea.js |
确保微信端可消费;必要时补小程序注入 |
| 公共顶栏 | miniprogram/components/app-safe-header.vue |
完善后供白底页复用,或抽出等效 SCSS |
| 地磅顶栏 | miniprogram/styles/db-theme.scss + 各地磅页 |
.db-header 改为方案 B 几何 |
| 报销顶栏 | miniprogram/styles/bx-theme.scss |
.topbar 对齐同一变量(替换仅 env(safe-area-inset-top) + 写死 58px) |
| 壳层大头 | miniprogram/styles/mp-shell.scss(及 mp-biz 变体) |
.mp-header* 使用 safe-top + capsule-right |
| 既有大背景头 | miniprogram/styles/index.scss .sq-hero-header |
核对已引用变量是否在微信端生效;无效则一并修通 |
| UI 规范 | docs/miniprogram-ui-spec-sanqiang.md §3.2 |
补充「自定义 Header 须适配胶囊」SHALL |
页面枚举以 pages.json 中 navigationStyle: custom 为准,至少覆盖:工作台、首页、待办、地磅全链路、报销全链路、占位页。
--sq-capsule-right-safe = 0)。getMenuButtonBoundingClientRect 在部分端或过早调用可能为空:已有默认值(safe-top≈20、nav=44、右侧 0/96);实现时保持兜底。mp-header--workbench 含额外 40px 偏移,改造时应用变量替换魔法数,避免双重叠加导致头部过高。miniprogram-ui-spec-sanqiang.md 中 Header 一小节。--sq-* 变量。