mobile-portrait-ui-iteration-spec
# 360x780 竖屏 UI 迭代规范(v1)
说明:本文基于当前项目的 360x780 竖屏实现、
docs/mobile-portrait-rulebook.md以及现有代码结构整理。标注图未在本轮对话中直接可见,个别与截图强相关的判断已标记为“需确认”。
适用边界
- 竖屏移动端:
360x780为首要基线。 - 横版 Web:保留更高信息密度,但不得把桌面式结构原样搬到手机。
- 共享组件:只承载内容,不承载整页布局决策。
- 现有代码参考:
src/App.tsx已存在isPortraitViewport分流,src/index.css已存在全局盒模型与竖屏滚动锁定基础。
A. 问题诊断表
| 分类 | 现状描述 | 根因判断 | 影响范围 | 优先级 |
| --- | --- | --- | --- | --- |
| 右侧溢出 / 横向滚动风险 | 360 宽度下,含图标、短标签、数值、房号标签 的组合块容易被挤压;如果某些长文本没有 min-width: 0,会把容器撑出可视宽度。部分问题需确认。 | Flex 子项缺少收缩约束,局部组件仍依赖固定宽度或过小字体来“救版面”。 | 顶栏、日志行、底部导航、轮盘浮窗、统计卡。 | P0 |
| 底部导航截断 / 安全区不足 | 底部 dock、主动作按钮、轮盘浮按钮、系统安全区之间距离偏紧,360 宽度下易发生遮挡或截断。 | 底部交互层级未统一,safe-area-inset-bottom 只做了局部补偿,未形成统一底部带。 | 底部导航、主动作区、轮盘入口、弹层底边。 | P0 |
| 圆角不一致 / 直角混用 | 同一屏内出现 18px、22px、24px、14px 等多种圆角,且卡片、按钮、浮层之间没有稳定对应关系。 | 缺少 radius token,组件按视觉感觉单独挑值。 | 所有按钮、卡片、sheet、弹窗。 | P1 |
| 阴影或层级覆盖标题 | Banner、标题、浮层和装饰层之间的 z-index 与阴影强度不统一,容易出现标题被压住、装饰层抢焦点的问题。 | 层级没有统一 token,装饰元素未明确禁止参与命中与遮挡。 | 顶栏、主图、弹层、卡片标题。 | P1 |
| 文本大小不统一 / 长文本压成单字 | 当前界面存在 7px、8px、9px 级文本,部分按钮和标签靠缩字撑版面,语义短文本可能被压成单字或极窄列。 | 字号没有统一 scale,靠局部缩放替代内容裁剪或语义重写。 | 顶栏、日志筛选、底栏、模块切换、统计标签。 | P0 |
| 动态文案格式缺括号 / 标点不稳定 | 动态计数、房号标签、组合标签、加减值文案在拼接时容易出现括号不成对、分隔符混乱、数值格式不一致。 | 动态文案直接字符串拼接,没有统一 formatter。 | 行囊、联机房号、资源标签、事件奖励、日志。 | P1 |
| 动作区域留白过大 / 容器比例失衡 | 某些区块为了“撑版面”留了过多 padding 或固定比例行高,导致内容显得松散,主内容与外壳比例失衡。 | 布局更像桌面堆栈,缺少移动端的内容优先级和压缩策略。 | 主动作区、日志卡、模块页。 | P1 |
| 首页与二级页职责混淆 | 竖屏首页仍承担过多管理型入口,二级模块与首页操作边界不够硬。 | 入口层和内容层没有完全拆开,部分模块仍把管理密度带回首页。 | 竖屏首页、抽屉、sheet、模块页。 | P1 |
B. 逐项修复方案
B0. 先给重构建议
- 把
src/App.tsx的布局决策拆成两个壳:MobilePortraitShell与DesktopWebShell。 - 把共享内容拆成
SharedHUD、SharedScene、SharedModuleSheet、SharedModalRoot、SharedActionDock。 - 让模块组件只负责内容,不再决定首页是单列、双列还是抽屉。
- 竖屏页面只允许一个主壳;桌面页允许左中右三段,但仍复用同一套 tokens。
B1. 右侧溢出 / 横向滚动风险
- 现状描述:长文案、数值、图标、标签混排时,局部 flex 子项容易被撑开。
- 预期效果:360 宽度下完全无横向滚动,所有文本在容器内自然换行或被正确截断。
- 代码级修复:
- 所有外层容器统一
width: 100%、max-width: 100%、box-sizing: border-box。 - 所有可收缩的 flex 子项补
min-width: 0。 - 需要单行的文本用
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;。 - 需要保留语义的长中文用
word-break: keep-all; overflow-wrap: anywhere;,不要压成单字。 - 列表摘要用
line-clamp-1或line-clamp-2,不要让摘要无限增长。 - 任何内嵌卡片都不要再嵌套一层“满宽卡片”来救布局。
- 所有外层容器统一
- 提炼规则:
- 文本先定上限,再定字号,最后才是换行。
- 不能靠缩字解决横向溢出。
B2. 底部导航截断 / 安全区不足
- 现状描述:底部 dock、主动作、轮盘按钮、sheet 底边距离偏近。
- 预期效果:所有底部交互位于拇指可达区,且不压住系统手势条。
- 代码级修复:
- 底部容器统一使用
padding-bottom: calc(<token> + env(safe-area-inset-bottom))。 - 底部 dock 与悬浮按钮分层,明确
z-index,不要共用同一条高度带。 - 360 宽度时,底部只保留 1 个主动作 + 2 个次动作,其余入口放进 sheet / 轮盘。
- 底部按钮的最小触达高度固定为
44px。 position: fixed元素必须先算安全区,再算视觉位置;轮盘这类入口可拖动,但落点必须再次 clamp 到屏内。
- 底部容器统一使用
- 提炼规则:
- 底部区域不是堆入口的地方,是收口和决策的地方。
B3. 圆角不一致 / 直角混用
- 现状描述:同屏多种圆角并存,视觉节奏不稳定。
- 预期效果:同类组件使用同一组圆角,不靠“看起来顺眼”临时改值。
- 代码级修复:
- 定义统一 radius tokens,不允许组件自选圆角。
- 卡片、列表项、普通按钮统一 8px 左右。
- sheet、浮层、桌面大面板可上升到 12px - 16px,但必须有明确语义。
- pill 类标签统一使用超大圆角,不混用小圆角。
- 不允许同一模块中,标题块和内容块使用完全不同的圆角逻辑,除非有明确层级语义。
- 提炼规则:
- 圆角是层级语言,不是装饰自由。
B4. 阴影或层级覆盖标题
- 现状描述:装饰层、封面图、标题、浮层之间可能出现压字或抢焦点。
- 预期效果:标题始终可读,装饰层永远不干扰阅读。
- 代码级修复:
- 装饰层统一
pointer-events: none。 - 文本层统一置于更高
z-index,但仅限内容层,不要无脑抬高所有元素。 - Banner、主图、封面图内部标题用
padding和overlay控制,不靠外部负 margin 抢位。 - 阴影只服务于分层,不服务于“更醒目”。
- 任何标题区域上方不允许出现不透明遮罩。
- 装饰层统一
- 提炼规则:
- 层级先保证可读,再谈氛围。
B5. 文本大小不统一 / 长文本压成单字
- 现状描述:7px、8px、9px 的微字号被拿来当常规信息,导致可读性下降。
- 预期效果:同级文本字号一致,标签语义完整,不出现单字截断。
- 代码级修复:
- 建立固定字号阶梯,不得在页面里临时降字号。
- 主标题、正文、说明、标签、徽章分别对应固定 token。
- 所有按钮文字优先两到四字短词;如果做不到,改图标+短名,不要硬压。
- 同一层级的数值型信息必须用同一字号。
- 仅徽章和极短状态允许 micro size。
- 提炼规则:
- 字号是信息等级,不是版面救火工具。
B6. 动态文案格式缺括号 / 标点不稳定
- 现状描述:动态拼接的标签、资源、房号标签、奖励信息容易出现括号不闭合或分隔符混乱。
- 预期效果:所有动态文案格式稳定,成对符号完整。
- 代码级修复:
- 所有动态文案必须通过 formatter 生成,不允许在 JSX 中直接长串拼接。
- 统一使用模板:
名称(A 3 / B 2)、房号标签:XXXXXX、奖励 +12 / -3。 - 对括号、分隔符、数值单位做输出校验,校验失败回退为安全格式。
- 中文标点和英数标点不要混用成一套“临时格式”。
- 提炼规则:
- 动态文案要先标准化,再渲染。
B7. 动作区域留白过大 / 容器比例失衡
- 现状描述:部分区域为了好看留白过多,导致内容与容器失衡。
- 预期效果:动作区紧凑但不拥挤,内容密度与容器高度匹配。
- 代码级修复:
- 动作区用
grid或稳定flex轨道,避免靠大 padding 撑比例。 - 内部滚动只允许发生在模块页 / sheet 内,不发生在首页主动作区。
- 统一
min-height,减少靠“空白补位”。 - 长模块放到抽屉、sheet 或二级页,不占首页主屏比例。
- 动作区用
- 提炼规则:
- 留白要服务阅读和操作,不是填充空洞。
B8. 首页与二级页职责混淆
- 现状描述:首页仍承担过多管理性内容,导致竖屏首屏不够干净。
- 预期效果:首页只保留看状态、看警报、做主动作;管理内容进入二级层。
- 代码级修复:
- 首页固定:HUD / 场景 / 日志摘要 / 主动作 / 少量导航。
- 二级模块统一进入 sheet / drawer / 独立页。
- 竖屏首页不允许出现桌面式侧栏原样搬运。
- 复杂模块内部可滚动,但首页不允许页面级滚动。
- 提炼规则:
- 首页负责决策,二级页负责管理。
C. 设计系统规范
C1. 模式矩阵
| 模式 | 屏幕法则 | 滚动法则 | 导航法则 | 密度法则 | | --- | --- | --- | --- | --- | | 竖屏移动端 | 只保留一屏以内的核心操作与反馈 | 首页不允许页面级滚动,二级层内允许滚动 | 底部 dock + sheet + 轮盘,入口数量受控 | 低密度、强优先级、强语义 | | 横版 Web | 允许更高信息密度与多栏布局 | 页面可滚,但模块内滚动仍要克制 | 顶部 tabs / 左右栏 / 侧边导航可并存 | 中高密度、分区明确、可比较 |
C2. Design Tokens
Spacing
| Token | Value | 用途 | 适用场景 | 禁用场景 |
| --- | --- | --- | --- | --- |
| space-1 | 4px | 最小间距单位 | 图标与文字、chip 内边距 | 页面主区块间距 |
| space-2 | 8px | 基础间距单位 | 按钮内边距、列表项、表格行 | 大屏主容器留白 |
| space-3 | 12px | 轻量分隔 | 卡片内段落、组块之间 | 需要强分区的主模块 |
| space-4 | 16px | 常规内容间距 | section 间距、sheet 内容间距 | 360 宽度下的底栏内边距过大 |
| space-5 | 20px | 较大留白 | Web 页面外层容器 | 竖屏首页主屏 |
| safe-bottom | env(safe-area-inset-bottom) | 适配系统手势条 | 底部 dock、sheet、浮窗 | 直接写死像素替代 |
Radius
| Token | Value | 用途 | 适用场景 | 禁用场景 |
| --- | --- | --- | --- | --- |
| radius-1 | 4px | 极小圆角 | 标签、细小按钮 | 主要卡片 |
| radius-2 | 8px | 卡片默认圆角 | 列表项、信息卡、普通按钮 | sheet 顶层容器 |
| radius-3 | 12px | 中层容器圆角 | sheet、抽屉、桌面面板 | 微型 chip |
| radius-4 | 16px | 大容器圆角 | Web 模块壳、对话框 | 高频小控件 |
| radius-pill | 9999px | pill 标签 | 状态条、计数器、筛选 chip | 需要明确边界的内容容器 |
Typography
| Token | Value | 用途 | 适用场景 | 禁用场景 |
| --- | --- | --- | --- | --- |
| font-brand | Noto Serif SC / Playfair Display | 品牌与题名气质 | 标题、品牌字样 | 长段正文 |
| font-body | Noto Serif SC | 正文阅读 | 说明、日志、内容区 | 数字表格密集区 |
| font-ui | Inter | 现代界面信息 | 数值、表格、辅助 UI | 品牌标题 |
| text-title | 16px / 1.3 | 主标题 | 竖屏标题、模块标题 | 徽章与标签 |
| text-body | 13px / 1.5 | 正文 | 说明、列表正文 | 主要按钮文案 |
| text-caption | 12px / 1.4 | 次级说明 | 时间、状态、辅助信息 | 主信息 |
| text-micro | 10px / 1.2 | 极短状态 | 徽章、角标、极短单位 | 任何正文、按钮主文案 |
| text-button | 12px - 13px / 1.2 | 交互文字 | 按钮、dock、sheet 操作项 | 过长句子 |
| text-metric | 18px / 1.1 | 数值强调 | 铜钱、声望、关键指标 | 长文本 |
Z-index
| Token | Value | 用途 | 适用场景 | 禁用场景 |
| --- | --- | --- | --- | --- |
| z-base | 0 | 基础层 | 普通内容 | 浮层 |
| z-content | 10 | 常规内容层 | 卡片、模块正文 | 罩层 |
| z-header | 20 | 顶栏层 | 头部 HUD | 模态遮罩 |
| z-dock | 40 | 底部交互层 | 主动作、dock、轮盘入口 | 覆盖 modal |
| z-sheet | 50 | 底部 sheet 层 | 模块抽屉、事件 sheet | 顶部导航 |
| z-modal | 60 | 模态层 | 弹窗、确认框 | 常规内容 |
| z-toast | 70 | 临时提示层 | 浮动提示、结果回执 | 常驻 UI |
Container
| Token | Value | 用途 | 适用场景 | 禁用场景 |
| --- | --- | --- | --- | --- |
| container-mobile | 100vw | 竖屏全宽容器 | 手机首页根容器 | 人工留白硬塞内容 |
| container-web | min(1680px, 100%) | Web 主容器 | 横版主屏、双栏布局 | 手机首页 |
| panel-max-mobile | 100% | 手机面板最大宽度 | sheet、卡片、弹层 | 固定大宽度 |
| panel-max-web | min(100%, 1680px) | Web 内容上限 | 桌面内容区 | 竖屏首页 |
| content-min | 0 | 允许收缩 | flex 子项、文本容器 | 所有需要撑版面元素 |
| touch-target-min | 44px | 最小触达高度 | 按钮、可点卡片 | 小于 44px 的主按钮 |
Text Rules
| 规则 | 用途 | 适用场景 | 禁用场景 |
| --- | --- | --- | --- |
| 主信息不低于 13px | 保证可读性 | 首页、模块标题、主要按钮 | 用 10px 代替排版 |
| 微字号只用于徽章 | 控制视觉噪音 | 角标、状态、单位 | 主文案、正文、操作按钮 |
| 单行标签用 ellipsis | 保持界面整齐 | 单行 chip、次级信息 | 主动作文案 |
| 多行摘要用 line-clamp | 控制卡片高度 | 日志、摘要、列表说明 | 关键操作说明 |
| 中文长标签先改语义再截断 | 防止单字化 | 页面标题、模块名、按钮名 | 直接把 4 字词压成 1 字 |
C3. 通用 Guidelines
- 同类组件必须共享同一套 tokens,不允许同页面临时改法。
- 竖屏首页只能有一个主动作区。
- 竖屏首页禁止页面级滚动;允许滚动的只有 sheet、drawer、独立页。
- 任何可点击区域都必须保留
cursor-pointer、44px以上触达高度与明确 hover / active 状态。 - 任何内容容器都必须先考虑
min-width: 0和overflow,再考虑视觉样式。 - 长文本优先改文案,不要只改字号。
- 动态文案优先通过 formatter 生成,不要直接字符串拼接。
- 装饰层不能抢占标题和按钮的层级。
- 卡片内部不要再嵌套同级大卡片。
D. 验收清单
- [ ] 360px 宽度无横向溢出。
- [ ] 所有组件完整可见,无截断。
- [ ] 底部导航和主动作不压住系统安全区。
- [ ] 同级文本字号一致。
- [ ] 长文本不出现单字截断。
- [ ] 动态文本括号成对完整。
- [ ] 圆角、层级、间距统一。
- [ ] 无页面级纵向滚动条。
- [ ] 重要标题不被阴影或装饰层覆盖。
- [ ] 375x812、390x844、412x915 仍保持同一套竖屏规则。
- [ ]
npm run lint与npm run build通过。
最小改动清单
必须改
- 竖屏根容器补齐安全区与底部收口。
- 全局补
min-width: 0、box-sizing: border-box、overflow-x: hidden。 - 统一手机字号阶梯,移除把 micro size 当正文的写法。
- 统一动态文案 formatter,修正括号与分隔符。
- 底部 dock / 固定锚点轮盘 / 主动作分层收口。
建议改
- 把
App.tsx拆成 mobile shell 和 web shell。 - 把共同卡片、按钮、chip 提炼成 token 驱动组件。
- 为日志、标签、房号、数值建立统一 formatter。
- 把重点模块改为 sheet / drawer / 独立页承载。
可后置
- 横版 Web 的三栏密度优化。
- 进一步统一动画时长与 easing。
- 增补更多机型的视觉回归记录。
结论
这份规范的核心不是“把当前页修漂亮”,而是把竖屏首页、横版 Web、二级模块的职责分开,并用 token 统一空间、字号、圆角、层级和文本规则。后续所有 UI 迭代都应先过这套约束,再进入具体实现。