重写全项目手机自适应架构
This commit is contained in:
@@ -1,164 +1,135 @@
|
||||
# 全项目手机视口自适应设计
|
||||
# 全项目手机自适应重构设计
|
||||
|
||||
## 背景与根因
|
||||
## 决策
|
||||
|
||||
2026-07-21 在 MuMu Android `720×1280 / 320dpi` 中复核 A01 时,默认登录态无法在首屏完整显示。设备应用可用区约为 `360×616dp`,而 A01 仍以固定 `1665rpx` 画布组织纵向布局;该画布在 `412×915` 中接近 915px,在 360dp 宽设备中仍约为 799dp,因此必然产生滚动。
|
||||
采用分阶段治理:先重构 A01 并在 MuMu 验收,再迁移 A04、A05 和封存 A06,最后按页面类型治理其余活动路由。不得继续在旧的整屏叠层结构上追加 `vh`、`rpx`、`clamp()` 或机型专用补丁。
|
||||
|
||||
问题不是 A01 单页偏差,而是项目级合同缺失:
|
||||
## 根因
|
||||
|
||||
- 52 个活动页面虽都有 `100vh` 或 `100dvh`,但只有 4 页直接声明顶部安全区、9 页声明底部安全区;
|
||||
- 22 页只有宽度断点,项目没有统一的高度连续适配规则;
|
||||
- A01、A04、A05、G01、G03、G05 仍存在大块固定 `rpx` 高度;
|
||||
- 现有容量合同检查固定高度、裁切和内容是否可达,但允许自然滚动,未检查固定流程页的核心操作是否在默认手机首屏完整可见;
|
||||
- 旧 A01 设计记录明确允许矮屏滚动,与用户本轮确认的产品要求冲突。
|
||||
当前问题不是 uni-app 的适配能力不足,而是页面把固定比例设计稿当成运行时坐标系:
|
||||
|
||||
用户确认的新合同是:整个项目必须适配手机可用视口;固定流程页在默认字体下首屏展示全部核心操作,长列表、详情和文章等长内容页自然滚动;所有页面都不得裁切、遮挡或依赖固定设计稿高度。
|
||||
- A 系列使用 `824×1830` 整页合成背景并以 `scaleToFill` 拉伸到任意屏幕比例。
|
||||
- 背景、印章和交互内容叠放在同一个 `grid-area: 1 / 1`,表单位置依赖背景中的视觉地标。
|
||||
- 旧 A01 使用 `1665rpx` 组织纵向画布;`rpx` 随屏宽换算,不能表达手机可用高度。在 MuMu 的约 `360×640dp` 视口中,该画布约为 `799dp`,必然超高。
|
||||
- 固定视口高度、整页叠层和独立的内容定位形成多套坐标;调整其中一套只能修复一个屏幕比例。
|
||||
|
||||
## 目标与边界
|
||||
对照项目 `3dyjsapp` 使用 `min-height: 100vh`、普通 Flex 文档流和装饰背景。内容尺寸由自身决定,空间不足时自然增长,因此不会依赖背景坐标或互相覆盖。
|
||||
|
||||
- 覆盖 `pages.json` 的全部 52 个活动路由,封存 A06 同步接受静态合同约束但不恢复路由。
|
||||
- 支持当前产品使用的竖屏手机形态;基础验证宽度为 320–480 CSS px,高度从 568 CSS px 起。
|
||||
- 默认系统字号下,固定流程页无需纵向滚动即可看到全部核心内容和主操作。
|
||||
- 长内容页允许自然滚动,必须保证末项可达、滚动所有权清晰、固定导航不遮挡内容。
|
||||
- 全部页面统一处理状态栏、刘海、底部手势区、固定 Header/Tabbar、软键盘和系统字体放大。
|
||||
- 不改变页面业务语义、路由、字段、状态和视觉主题;不重绘或删除当前资产。
|
||||
- 横屏不纳入本轮视觉排版目标;本轮不得通过未声明的横屏规则影响现有竖屏布局。
|
||||
## 架构原则
|
||||
|
||||
## 选择方案
|
||||
### 背景与布局解耦
|
||||
|
||||
采用“统一视口合同 + 页面滚动分类 + 路由保留业务布局”。
|
||||
- 背景只负责装饰,不得决定标题、输入框、按钮或列表的位置。
|
||||
- 禁止普通页面使用整页合成图的 `scaleToFill` 作为布局基准。
|
||||
- 屋檐、横幅等有明确比例的头图必须放入独立槽位,使用 `widthFix` 或显式 `aspect-ratio`,高度由宽度推导,不做纵向拉伸。
|
||||
- 宣纸、云纹、树影等可重复或可裁切纹理作为内容区背景,允许 `cover` 或分层装饰,但不得承载交互坐标。
|
||||
- 装饰层可以重叠;交互内容必须处于正常文档流,除弹窗、浮层和真实画布节点外不得整页绝对定位或整页网格叠放。
|
||||
|
||||
不把 52 页全部重包进一个通用页面组件,避免再次形成业务与布局耦合;不允许每页自行维护机型断点。共享层只拥有视口、安全区、触控下限和连续间距原语,每个路由继续拥有自己的内容结构。
|
||||
### 单一视口所有者
|
||||
|
||||
## 单一所有者
|
||||
`styles/global.scss` 只拥有以下全局原语:动态视口高度、安全区、共享 Header/Tabbar 占位、最小触控尺寸和少量连续间距变量。页面消费这些原语,但不得按品牌或具体型号复制视口规则。
|
||||
|
||||
### 运行时视口原语
|
||||
全局视口变量只解决浏览器或 WebView 的可用高度差异,不能用于重新创建一套设计稿坐标系。
|
||||
|
||||
`styles/global.scss` 是以下规则的唯一运行时所有者:
|
||||
### 页面类型
|
||||
|
||||
- 动态可用视口高度及 `100vh` 兼容回退;
|
||||
- 顶部、底部安全区变量;
|
||||
- 固定 Header 和 Tabbar 的占位变量;
|
||||
- 约 44dp 的最小触控尺寸;
|
||||
- 小屏到高屏连续变化的垂直间距、装饰尺寸和内容留白变量;
|
||||
- 三类页面壳的基础行为。
|
||||
每个活动路由必须且只能归入一种布局类型:
|
||||
|
||||
页面可以消费这些变量,不能重新定义同义常量或按具体手机型号复制一套视口规则。
|
||||
1. `document-flow`:列表、详情、文章和长表单。根容器使用最小视口高度,内容自然撑高,页面是唯一纵向滚动所有者。
|
||||
2. `compact-flow`:登录、短确认和固定步骤页。默认字号、无键盘时应在目标基线视口完整显示;内容仍使用正常文档流,极端小屏、大字号、错误文案或键盘状态允许自然滚动。
|
||||
3. `split-viewport`:固定 Header/筛选区加独立内容滚动区。页面自身不与内容区形成双重纵向滚动。
|
||||
4. `interactive-canvas`:家谱关系图等真实画布。画布占据计算后的可用视口,内部负责缩放和平移;页面表单、说明和操作栏仍遵守正常流与安全区。
|
||||
|
||||
### 路由分类
|
||||
分类只定义高度和滚动所有权,不承载业务字段、状态或视觉内容。
|
||||
|
||||
新增一个精确路由清单作为页面分类唯一所有者。`pages.json` 中每个活动路由必须且只能属于一类;缺失路由、重复路由和已删除路由均使合同失败。
|
||||
## A 系列结构
|
||||
|
||||
初始分类:
|
||||
新增共享认证页骨架,供 A01、A04、A05 和封存 A06 使用。骨架只拥有:
|
||||
|
||||
- `viewport-fit`:A01、A04、A05、T08、F10。默认态内容有确定上限,默认字号下必须完整进入首屏。
|
||||
- `split-scroll`:G01、T01、T07。页面壳固定,只有指定内容区域滚动;T01 继续保留明确的横向世系画布滚动。
|
||||
- `document-scroll`:其余 44 个活动路由。内容随数据自然增长,由页面文档流承担唯一纵向滚动。
|
||||
- 顶部安全区;
|
||||
- 固定比例的品牌头图槽;
|
||||
- 独立的宣纸内容区背景;
|
||||
- 正常文档流内容槽;
|
||||
- 底部安全区和溢出回退。
|
||||
|
||||
封存 A06 按 `viewport-fit` 静态检查,但不计入 52 页活动路由统计。
|
||||
各认证页面继续拥有自己的标题、字段、状态、操作和业务逻辑。共享骨架不得成为业务配置中心,也不得用页面编号切换业务 DOM。
|
||||
|
||||
分类只决定视口和滚动合同,不提供标题、字段、状态或动作,不能成为新的业务目录配置。
|
||||
A01 默认态的纵向压缩顺序为:装饰留白、装饰尺寸、非关键间距、辅助说明;标题、正文、输入框、按钮和协议触控区域不得低于可读和可触控下限。禁止整页 `transform: scale()`。
|
||||
|
||||
## 三类页面行为
|
||||
## 安全区、键盘与字体
|
||||
|
||||
### `viewport-fit`
|
||||
- 同一安全区只能由一个层级计入;共享 Header、Tabbar 或认证页骨架拥有后,业务页面不得重复叠加。
|
||||
- 默认系统字号执行各页面类型的首屏或滚动合同。
|
||||
- 约 1.3 倍系统字号下允许 `compact-flow` 回退为自然滚动,但不得裁字、遮挡或丢失操作。
|
||||
- 键盘弹出时必须能滚动到焦点字段、就近错误信息和当前主操作;键盘收起后页面恢复合理位置。
|
||||
- 弹窗、底部弹层和全屏预览各自拥有最大高度、安全区和内部滚动,不计入页面默认内容高度。
|
||||
|
||||
- 页面最小高度等于实际可用动态视口,默认态不得依赖固定设计稿高度。
|
||||
- 默认字体、无键盘状态下,`scrollHeight` 不超过可用 `clientHeight` 的像素舍入容差。
|
||||
- 背景、印章、标题和留白优先使用 `clamp()` 随可用高度连续缩放。
|
||||
- 输入框、按钮、切换项、注册链接和协议勾选保持约 44dp 触控下限。
|
||||
- 不允许整页 `transform: scale(...)`,不允许隐藏核心入口,不允许把核心操作移出首屏。
|
||||
- 错误文案、软键盘或系统字体放大使内容超出时,页面回退为自然滚动,不裁字、不重叠。
|
||||
## 分阶段迁移
|
||||
|
||||
### `document-scroll`
|
||||
### 阶段一:A01 结构证明
|
||||
|
||||
- 页面根容器至少填满动态可用视口,正文由正常文档流自然撑高。
|
||||
- 页面只保留一个纵向滚动所有者;列表、详情、文章和长表单不得使用固定设计稿高度限制内容容量。
|
||||
- 主操作不要求始终固定在首屏,但必须按流程顺序可达,且末项和底部按钮位于安全区及固定 Tabbar 之上。
|
||||
- 空、加载、失败和短内容状态至少填满可用内容区,不能因内容少而露出错误背景或产生无意义双滚动。
|
||||
- 删除 A01 的整页合成背景布局职责和全屏叠层坐标。
|
||||
- 将品牌头图、宣纸内容区和登录内容拆为独立结构。
|
||||
- 保持登录方式、校验、协议和跳转逻辑不变。
|
||||
- 只有 A01 在 MuMu 默认密码态和验证码态均通过后,才能提取共享认证页骨架。
|
||||
|
||||
### `split-scroll`
|
||||
### 阶段二:认证页迁移
|
||||
|
||||
- Header、摘要、筛选或代际栏等固定区域明确占位,指定内容区获得剩余可用高度。
|
||||
- 页面文档本身不得与内部内容区同时纵向滚动。
|
||||
- G01 列表、T07 目录和 T01 世系画布保持各自唯一滚动所有权;固定区域不得遮住首项或末项。
|
||||
- T01 横向画布滚动与纵向视口分工继续由页面专属合同维护。
|
||||
- 从已验证的 A01 结构中提取最小共享骨架。
|
||||
- 迁移 A04、A05 和封存 A06,不恢复 A06 路由。
|
||||
- 验证长表单、错误、提交中、成功、键盘和返回保护状态。
|
||||
|
||||
## 安全区与固定导航
|
||||
### 阶段三:项目页面分类治理
|
||||
|
||||
- `PageHeader` 继续统一拥有顶部安全区和页面顶部占位。
|
||||
- `AppTabbar` 继续统一拥有底部安全区和页面底部占位。
|
||||
- 没有 Header 或 Tabbar 的页面从全局页面壳消费安全区变量,不得硬编码状态栏或手势区高度。
|
||||
- 同一安全区只能由一个层级计入,禁止页面与共享导航重复叠加。
|
||||
- 页面背景可以延伸到系统区域,交互内容和关键文字不能进入不可安全触控区域。
|
||||
- 建立活动路由到四类页面的唯一清单。
|
||||
- 优先处理现有整屏 `grid-area: 1 / 1`、`scaleToFill`、固定大块高度和 `overflow: hidden` 风险页。
|
||||
- 再迁移普通列表、详情、文章、表单和共享 Header/Tabbar/Dialog。
|
||||
- 真正的家谱画布保留独立视口策略,不套用普通文档页规则。
|
||||
|
||||
## 连续适配规则
|
||||
每一批迁移必须独立验收,不允许一次性机械替换全部页面后再集中修复。
|
||||
|
||||
- 使用 `clamp(最小值, 视口相关计算值, 设计基准值)` 连续调整纵向尺寸,不按品牌、型号或单一分辨率写专用规则。
|
||||
- `rpx` 继续用于与屏宽相关的横向比例和资产尺寸,但不得单独承担整页纵向高度合同。
|
||||
- 纵向压缩顺序为:装饰留白 → 装饰尺寸 → 非关键间距 → 非关键说明字号;核心文字、输入和操作触控尺寸最后压缩且不得低于下限。
|
||||
- 固定像素仅用于最小触控面积、1px 线条或经审计的资产槽位,不用于限制可变正文容量。
|
||||
- 旧 `1665rpx` 等设计画布高度、重复的 `100vh` 页面壳和失效风险白名单在迁移后删除,不保留兼容分支。
|
||||
## 静态合同
|
||||
|
||||
## 字体、键盘与异常状态
|
||||
新增或修订项目级合同,至少检查:
|
||||
|
||||
- 默认字号执行页面分类的首屏或滚动合同。
|
||||
- 约 1.3 倍系统字号下允许 `viewport-fit` 页面回退为自然滚动,但所有文字必须完整、操作必须可达。
|
||||
- 输入框聚焦时,软键盘不得遮挡当前字段、就近错误文案或当前主操作;页面应能滚动到焦点并在键盘收起后恢复合理位置。
|
||||
- Toast、Dialog、底部弹层和全屏预览拥有独立覆盖层,不计入页面默认内容高度;它们各自处理安全区、长文案和内部滚动。
|
||||
- 加载、空、失败、权限和成功状态必须按所属页面类别验证,不能只验证正常态。
|
||||
- `pages.json` 的全部活动路由均有且只有一个布局分类,封存页面单独声明。
|
||||
- 普通交互页禁止整页 `scaleToFill` 合成背景、整页交互叠层和固定设计稿画布高度。
|
||||
- `document-flow` 只有一个纵向滚动所有者,末项可达。
|
||||
- `compact-flow` 保留自然溢出回退,禁止通过裁切或整页缩放满足首屏。
|
||||
- `split-viewport` 明确固定区和唯一内容滚动区。
|
||||
- 固定高度白名单必须精确到文件、选择器、风险类型和理由,失效条目使合同失败。
|
||||
|
||||
## 合同迁移
|
||||
## 运行时与设备验收
|
||||
|
||||
### 静态合同
|
||||
自动化视口检查覆盖至少:`320×568`、`360×640`、`375×812`、`390×844`、`412×915` 和 `480×1040` CSS px。
|
||||
|
||||
新增项目级手机视口合同并先在当前代码上失败,至少检查:
|
||||
共同要求:
|
||||
|
||||
- 52 条活动路由与分类清单一一对应;
|
||||
- 页面使用全局视口原语,不重新声明旧页面壳常量;
|
||||
- 禁止活动页面以固定大块 `rpx/px` 高度承担整页或正文布局;
|
||||
- 禁止整页缩放、重复安全区、双纵向滚动和无所有者的固定导航避让;
|
||||
- 允许图标、缩略图、印章、按钮槽位和 T01 节点等经过精确说明的固定视觉边界;
|
||||
- 白名单必须精确到文件、选择器、风险类型和原因,并拒绝失效项。
|
||||
- 无水平溢出、关键控件越界、正文裁切和双重纵向滚动。
|
||||
- 固定 Header/Tabbar 与安全区不遮挡首项、末项或主操作。
|
||||
- 头图保持比例,背景裁切不改变内容坐标。
|
||||
- 大字号、错误文案和键盘状态下所有字段及操作可达。
|
||||
|
||||
现有数据容量合同继续负责数据数量和正文增长;新合同负责手机视口、首屏、滚动所有权和安全区。两者职责不得混写。
|
||||
Android 视觉结论必须来自模拟器或真机,H5 只能作为自动化辅助,不能替代 Android 验收。第一基线为当前 MuMu `720×1280 / 320dpi`(约 `360×640dp`)。
|
||||
|
||||
### H5 运行合同
|
||||
A01 阶段一完成条件:
|
||||
|
||||
全部 52 个活动路由至少验证:
|
||||
- 默认密码态和验证码态无需纵向滑动即可看到完整协议区。
|
||||
- 页面没有屋檐与标题重叠,宣纸分界与内容之间保留稳定留白。
|
||||
- 头图无纵向拉伸,输入、按钮和协议区域满足最小触控尺寸。
|
||||
- 未勾选协议、输入错误、键盘弹出和键盘收起状态均无裁切,操作可达。
|
||||
- 用户查看 MuMu 原生画面并确认视觉方向后,才迁移其他认证页。
|
||||
|
||||
- `320×568`、`360×616`、`360×640`、`360×800`、`412×915`、`480×1040`;
|
||||
- 无横向溢出、无关键控件越界、无双纵向滚动;
|
||||
- 安全区和固定导航不遮挡首项、末项及主操作;
|
||||
- `viewport-fit` 默认态无纵向滚动;
|
||||
- `document-scroll` 末项可达且滚动位置稳定;
|
||||
- `split-scroll` 只有声明的内容区滚动;
|
||||
- 默认字号和约 1.3 倍字号均不裁字、不重叠。
|
||||
## 非目标
|
||||
|
||||
流程页还需覆盖表单错误、提交中、失败、成功和返回保护等适用状态。
|
||||
|
||||
### Android 验证
|
||||
|
||||
- 先以当前 MuMu `720×1280 / 320dpi` 作为 Android 基线,逐模块复核代表页和全部 `viewport-fit` 页面。
|
||||
- A01 必须重新截取密码、验证码、错误、协议和键盘状态;默认密码与验证码状态无需滑动即可看到完整协议区。
|
||||
- 每个模块至少检查一个短内容状态和一个长内容状态;固定 Header/Tabbar、系统返回、软键盘和底部手势区必须真实操作。
|
||||
- H5 自动结果不能替代 Android 证据或用户视觉确认。
|
||||
|
||||
## 执行顺序
|
||||
|
||||
1. 建立失败的路由分类、静态视口和全路由运行合同。
|
||||
2. 建立全局视口、安全区、触控和三类页面壳原语。
|
||||
3. 先修 A01 并在 MuMu 证明新合同可解决已复现问题。
|
||||
4. 迁移 A04、A05、封存 A06,再迁移 G01、T01、T07 三个特殊滚动页。
|
||||
5. 按 G → T → F → R → N → M 迁移剩余 `document-scroll` 页面。
|
||||
6. 运行全路由六档 H5、字体压力、状态合同和 MuMu 模块复核。
|
||||
7. 用户逐页确认发生可见变化的页面;自动验证不得直接新增或维持 `[x]`。
|
||||
- 不改变业务接口、路由、字段、状态机和文案语义。
|
||||
- 不借自适应重构重新设计整个视觉主题。
|
||||
- 不为单个品牌或型号建立专用断点。
|
||||
- 不承诺在任意内容量、任意字号和键盘同时打开时完全无滚动;承诺默认基线首屏完整,异常条件下无裁切且可自然到达。
|
||||
|
||||
## 完成条件
|
||||
|
||||
- 52 个活动路由全部纳入且通过项目级手机视口合同,无失效白名单。
|
||||
- A01 在当前 MuMu 默认密码和验证码状态首屏完整,无需滑动。
|
||||
- 六档 H5 的全部路由通过对应类别合同。
|
||||
- 默认字号、1.3 倍字号、软键盘、安全区、固定导航和返回行为均有相应证据。
|
||||
- 旧固定页面高度和旧自适应说明从运行时、验证器、设计记录、验收规划和交接记录中同步移除。
|
||||
- Android 结论只覆盖实际验证的设备和状态,不把模拟器结果扩写为所有真机最终通过。
|
||||
- A01、认证页和其余活动路由按阶段完成真实设备验收。
|
||||
- 所有活动路由拥有唯一布局分类,并通过对应静态和运行时合同。
|
||||
- 旧固定设计稿画布、整页合成背景坐标、重复视口规则和失效白名单从运行时、测试、设计记录与交接记录中同步移除。
|
||||
- Android 结论只覆盖实际验证的设备、分辨率和状态,不把单一模拟器结果扩写为所有真机已通过。
|
||||
|
||||
Reference in New Issue
Block a user