# H5 原型 → 微信小程序迁移桥接规范 版本:v1.0 基于:`docs/h5_ui/` 原型代码穷举审阅 + Tailwind CSS v3 CDN 默认配置 + 微信 WXSS rpx 官方定义 适用:本项目所有 H5 原型页面到小程序页面的迁移工作 --- ## 0. 尺寸换算基础(核心依据) ### 0.1 Tailwind CSS 在 412px 设备上的渲染行为 本项目 H5 原型使用 ``(Tailwind CSS v3 CDN Play 模式)。 Tailwind v3 默认主题中,大量 spacing、font-size、border-radius token 主要使用 `rem` 体系(默认 spacing scale 中除 `0`(0px)和 `px`(1px)外,其余均为 rem);但 Tailwind 并非所有尺寸都基于 rem,仍可能出现 px、百分比(`w-1/2`)、分数、视口单位(`min-h-screen`)、自定义 arbitrary 值(`h-[38px]`)等。 在浏览器默认根字号 `1rem = 16px` 且页面未主动改写 `html { font-size }` 的前提下,这些 rem 体系的 utility 会计算成固定 CSS px 值。这个值不随设备宽度变化——在 320px、375px、412px 的设备上,`p-4`(`1rem`)始终渲染为 `16px`。 原型的 `` 意味着:在浏览器按 `width=device-width` 建立布局视口、且该设备当前等效布局宽度为 412 CSS px 的前提下,页面宽度按 412 CSS px 参与布局。 因此:**Tailwind 默认 rem 体系的 utility class 在任何设备上都会计算为固定的 CSS px 值**,与设备布局宽度无关。但百分比、视口单位、自定义值等非 rem 单位仍会随设备变化。 ### 0.2 微信 rpx 的精确定义 来源:[微信官方 WXSS 文档](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html) > rpx(responsive pixel):可以根据屏幕宽度进行自适应。规定屏幕宽为 750rpx。 换算公式: ``` 1rpx = 屏幕宽度px / 750 1px = 750 / 屏幕宽度px × rpx ``` 官方示例: | 设备 | 屏幕宽度 | 1rpx = ?px | 1px = ?rpx | |------|----------|-----------|-----------| | iPhone 5 | 320px | 0.42px | 2.34rpx | | iPhone 6 | 375px | 0.5px | 2rpx | | iPhone 6 Plus | 414px | 0.552px | 1.81rpx | ### 0.3 本项目的换算链路 验收基准设备:等效宽度 412px 完整链路:`Tailwind class → CSS 计算值(px) → rpx` ``` rpx = CSS_px × (750 / 412) = CSS_px × 1.82039... ``` 但这里有一个关键问题:**rpx 是响应式单位,px 是固定单位**。 在 412px 设备上:`750rpx = 412px`,所以 `1rpx ≈ 0.549px` 在 375px 设备上:`750rpx = 375px`,所以 `1rpx = 0.5px` 在 320px 设备上:`750rpx = 320px`,所以 `1rpx ≈ 0.427px` 而 H5 原型中 Tailwind 的 `p-4 = 16px` 在所有设备上都是 16px。如果我们把它转成 `29rpx`(16 × 1.82),那么: - 在 412px 设备上:29rpx = 29 × 0.549 = 15.93px ≈ 16px ✓ - 在 375px 设备上:29rpx = 29 × 0.5 = 14.5px ✗(比原型小 9.4%) - 在 320px 设备上:29rpx = 29 × 0.427 = 12.38px ✗(比原型小 22.6%) 这意味着:**用 rpx 无法在所有设备上精确还原 H5 原型的固定 px 值**。rpx 的本质是按屏宽缩放,适合保持比例;px 的本质是固定绝对尺寸,适合贴近 H5 原型的绝对视觉值。二者不能在所有设备上同时做到完全等价。 ### 0.4 本项目的尺寸单位策略 H5 原型是移动端单栏布局,没有使用响应式断点。在 412px 设备上验收。 用 rpx 可以在不同宽度设备上保持相对比例一致;用固定 px 更接近 H5 原型的绝对尺寸视觉。二者不能在所有设备上同时做到完全等价。 **推荐策略:以 rpx 为主、px 为辅的混合单位方案。** rpx 适用场景(跟屏宽强相关的尺寸): - 页面外层容器宽度、横向间距、卡片宽度、栅格 - 吸顶区高度、块级间距 - 大尺寸元素的 padding / margin px 适用场景(需要绝对精度或极小尺寸): - `1px` 发丝线边框(`border: 1px solid`) - 阴影的模糊半径和扩散半径(`box-shadow` 的 blur/spread) - 极小的装饰元素(2px 以下的点、线) - icon 实际绘制尺寸(12/14/16/18/20px 等常见图标尺寸) - 绝对定位微调(badge 偏移 `top`/`right`) - 弹层阴影、蒙层模糊参数 - 评分星星、勾选框、状态点等小控件 - 自定义导航栏中的状态栏补偿(通常结合 `wx.getSystemInfoSync()` 动态计算,不是纯 rpx 公式能解决) 按实际效果决定(不一刀切): - 文本字号、图标尺寸、圆角、局部 padding 理由: 1. 小程序的主要使用场景是手机,屏幕宽度在 320-428px 之间,rpx 的等比缩放在这个范围内视觉差异可接受 2. 微信官方推荐使用 rpx 做适配,但并未要求所有样式都必须用 rpx;WXSS 也支持直接写 px 3. 412px 是验收基准,在该设备上 rpx 换算后的值与原型一致 4. 固定 px 在小屏设备上可能导致内容溢出或布局挤压,但在细节尺寸上能保持质感 5. 全面 rpx 在小尺寸上容易出现"比例上没错,但质感不对"的问题 **换算公式(rpx 场景使用):** ``` rpx = H5_CSS_px × (750 / 412) ≈ H5_CSS_px × 1.8204 ``` 取整规则: - 常规布局值:四舍五入到整数 rpx - 高频出现的设计 token:沉淀成统一变量表(如 §1.1 换算表),保持全项目一致 - 对视觉特别敏感的值:以真机截图比对微调,不强行套公式 --- ## 1. Tailwind Spacing → rpx 完整换算表 Tailwind v3 的 spacing scale 基于 `0.25rem = 4px` 步进。以下是本项目原型中实际使用的所有 spacing 值的精确换算。这些 rpx 值已在已迁移页面中使用,作为项目统一 token,后续页面应保持一致。 ### 1.1 Tailwind spacing scale(默认) | Tailwind 值 | rem | CSS px | rpx(项目 token) | 常见用途 | |-------------|-----|--------|---------------------|---------| | `0.5` | 0.125rem | 2px | 4rpx | gap-0.5, p-0.5, mt-0.5 | | `px` | 1px | 1px | 2rpx | py-px, w-px | | `1` | 0.25rem | 4px | 8rpx | gap-1, p-1, mt-1, mb-1 | | `1.5` | 0.375rem | 6px | 12rpx | gap-1.5, p-1.5, mt-1.5 | | `2` | 0.5rem | 8px | 14rpx | gap-2, p-2, mt-2, mb-2 | | `2.5` | 0.625rem | 10px | 18rpx | gap-2.5, p-2.5, mb-2.5 | | `3` | 0.75rem | 12px | 22rpx | gap-3, p-3, mb-3, pl-3 | | `3.5` | 0.875rem | 14px | 26rpx | p-3.5, h-3.5, w-3.5 | | `4` | 1rem | 16px | 30rpx | gap-4, p-4, px-4, mb-4 | | `5` | 1.25rem | 20px | 36rpx | p-5, px-5, mb-5, pb-5 | | `6` | 1.5rem | 24px | 44rpx | gap-6, p-6, px-6, mb-6 | | `7` | 1.75rem | 28px | 52rpx | h-7, w-7 | | `8` | 2rem | 32px | 58rpx | px-8, mb-8, pb-8, h-8 | | `9` | 2.25rem | 36px | 66rpx | h-9, w-9 | | `10` | 2.5rem | 40px | 72rpx | h-10, w-10, pb-10 | | `11` | 2.75rem | 44px | 80rpx | h-11, w-11, ml-11 | | `12` | 3rem | 48px | 88rpx | h-12, w-12, pb-12, left-12 | | `14` | 3.5rem | 56px | 102rpx | h-14, w-14 | | `16` | 4rem | 64px | 116rpx | h-16, w-16 | | `20` | 5rem | 80px | 146rpx | h-20, w-20, top-20 | | `24` | 6rem | 96px | 174rpx | h-24, w-24 | | `28` | 7rem | 112px | 204rpx | h-28, w-28 | | `32` | 8rem | 128px | 232rpx | h-32, w-32 | | `40` | 10rem | 160px | 292rpx | bottom-40, top-40 | | `64` | 16rem | 256px | 466rpx | h-64 | | `72` | 18rem | 288px | 524rpx | w-72 | ### 1.2 Arbitrary spacing 值 | Tailwind class | CSS 值 | rpx | |---------------|--------|-----| | `h-[38px]` / `w-[38px]` | 38px | 70rpx | | `top-[44px]` | 44px | 80rpx | | `min-h-[2.5rem]` | 40px | 72rpx | | `max-h-[70vh]` | 70vh | 70vh(保留 vh) | --- ## 2. Tailwind 字号 → WXSS font-size + line-height 完整换算表 ### 2.1 核心事实 Tailwind v3 的字号类(`text-xs`、`text-sm` 等)同时设置 `font-size` 和 `line-height`。这是 Tailwind 的内置行为,不是可选的。 例如 `text-sm` 生成的 CSS 是: ```css font-size: 0.875rem; /* 14px */ line-height: 1.25rem; /* 20px */ ``` 如果 WXSS 只写了 `font-size` 而没写 `line-height`,小程序会使用默认行高(约 1.2 倍字号),导致每行文字的垂直空间不足,整体高度偏矮。 **强制规则:每个 Tailwind 字号类转 WXSS 时,必须同时写 `font-size` 和 `line-height`。** ### 2.1.1 微信小程序 text 组件的 line-height 限制 ⚠️ **关键发现**:微信小程序的 `` 组件不能直接设置 `line-height`,必须通过外层 `` 设置。 **正确做法:** ```wxss /* 全局设置 */ page { line-height: 1.5; /* Tailwind 默认行高 */ } view { line-height: inherit; /* view 继承 page 的 line-height */ } /* text 会自动继承外层 view 的 line-height,不需要额外设置 */ ``` **局部覆盖:** ```wxss .section-title { font-size: 26rpx; line-height: 36rpx; /* 在 view 的 class 上设置,text 会继承 */ font-weight: 600; } ``` ```wxml 标题文本 ``` **错误做法:** ```wxss /* ❌ 直接在 text 上设置 line-height 无效 */ text { line-height: 36rpx; /* 不会生效 */ } /* ❌ 添加 display: inline-block 也无效 */ text { display: inline-block; line-height: 36rpx; /* 仍然不会生效 */ } ``` **原因**:微信小程序的 `` 是特殊的内联组件,直接设置 `line-height` 不生效,必须在外层 `` 上设置。 **验证方法**:在开发者工具的 Computed 面板中,text 元素不会显示 `line-height` 属性,但外层 view 的 `height` 值会包含行高效果。 ### 2.2 标准字号类换算表 Tailwind v3 默认字号定义(来源:Tailwind CSS v3 源码 `defaultTheme.js`): | Tailwind class | font-size (rem) | font-size (px) | line-height (rem) | line-height (px) | WXSS font-size | WXSS line-height | |---------------|----------------|---------------|-------------------|-----------------|----------------|-----------------| | `text-xs` | 0.75rem | 12px | 1rem | 16px | 22rpx | 30rpx | | `text-sm` | 0.875rem | 14px | 1.25rem | 20px | 26rpx | 36rpx | | `text-base` | 1rem | 16px | 1.5rem | 24px | 30rpx | 44rpx | | `text-lg` | 1.125rem | 18px | 1.75rem | 28px | 32rpx | 52rpx | | `text-xl` | 1.25rem | 20px | 1.75rem | 28px | 36rpx | 52rpx | | `text-2xl` | 1.5rem | 24px | 2rem | 32px | 44rpx | 58rpx | | `text-3xl` | 1.875rem | 30px | 2.25rem | 36px | 54rpx | 66rpx | ### 2.3 Arbitrary 字号换算表 原型中使用的 arbitrary 字号(`text-[Npx]`)没有 Tailwind 内置的 line-height 绑定。浏览器会使用默认行高(通常为 `normal`,约 1.2 倍字号)。 | Tailwind class | font-size (px) | 默认 line-height (px, ×1.2) | WXSS font-size | WXSS line-height | |---------------|---------------|----------------------------|----------------|-----------------| | `text-[9px]` | 9px | ~10.8px | 16rpx | 20rpx | | `text-[10px]` | 10px | ~12px | 18rpx | 22rpx | | `text-[11px]` | 11px | ~13.2px | 20rpx | 24rpx | | `text-[12px]` | 12px | ~14.4px | 22rpx | 26rpx | | `text-[13px]` | 13px | ~15.6px | 24rpx | 28rpx | 注意:arbitrary 字号在原型中使用频率极高(`text-[10px]` 157 次、`text-[11px]` 230 次),是本项目的主力小字号。 ### 2.4 font-weight 映射 | Tailwind class | CSS font-weight | WXSS | |---------------|----------------|------| | `font-normal` | 400 | `font-weight: 400` | | `font-medium` | 500 | `font-weight: 500` | | `font-semibold` | 600 | `font-weight: 600` | | `font-bold` | 700 | `font-weight: 700` | **注意:`font-medium` 是 500 不是 600。** 这是常见错误。 ### 2.5 其他文本属性 | Tailwind class | CSS | WXSS | |---------------|-----|------| | `text-center` | `text-align: center` | `text-align: center` | | `text-right` | `text-align: right` | `text-align: right` | | `text-left` | `text-align: left` | `text-align: left` | | `truncate` | `overflow: hidden; text-overflow: ellipsis; white-space: nowrap` | 同左 | | `line-clamp-2` | `-webkit-line-clamp: 2; display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden` | 同左(小程序支持) | | `whitespace-nowrap` | `white-space: nowrap` | `white-space: nowrap` | | `leading-normal` | `line-height: 1.5` | `line-height: 1.5` | | `leading-relaxed` | `line-height: 1.625` | `line-height: 1.625` | | `leading-snug` | `line-height: 1.375` | `line-height: 1.375` | | `tracking-wide` | `letter-spacing: 0.025em` | `letter-spacing: 0.025em` | | `underline` | `text-decoration: underline` | `text-decoration: underline` | | `line-through` | `text-decoration: line-through` | `text-decoration: line-through` | --- ## 3. Tailwind 颜色 → WXSS 颜色完整映射 ### 3.1 项目自定义颜色(tailwind.config.theme.extend.colors) 每个 HTML 页面的 `