Files
Starlight_Lancher/.agents/skills/oil-frontend/references/viewport-and-dialog-contract.md

197 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 页面尺寸与弹窗规则
> 当任务涉及页面或弹窗尺寸、分栏、滚动、承载方式或响应式布局时读取;依附触发器的浮层由下拉菜单与浮层规则负责。
## 目录
- [核心模型](#核心模型)
- [单屏信息预算](#单屏信息预算)
- [水平与垂直布局](#水平与垂直布局)
- [内容驱动尺寸](#内容驱动尺寸)
- [滚动由谁负责](#滚动由谁负责)
- [弹窗结构](#弹窗结构)
- [操作栏](#操作栏)
- [承载方式:弹窗、抽屉与完整页面](#承载方式弹窗抽屉与完整页面)
- [响应式](#响应式)
- [审查问题](#审查问题)
## 核心模型
先确定四个问题:
1. 首屏必须让用户看到什么;
2. 内容如何决定尺寸并受视口约束;
3. 哪个区域拥有滚动;
4. 主操作固定在哪里。
空间设计按以下顺序进行:
`删除非必要信息 → 使用水平空间 → 压缩重复间距 → 指定滚动区 → 才允许增加页面长度`
## 单屏信息预算
首屏优先显示:
- 当前对象身份;
- 当前任务或关键预览;
- 影响决策的状态;
- 主要操作;
- 完成任务必需的输入。
以下内容可以滚动或进入详情:
- 历史记录;
- 完整分析和证据;
- 低频设置;
- 帮助说明;
- 次要关联信息。
不要为了“单屏”缩小到难以阅读。目标是减少无意义滚动,让用户在首屏完成主要判断和操作。
## 水平与垂直布局
宽屏优先并列展示可以同时参考的信息:
- 媒体预览 + 配置;
- 资源身份 + 详情;
- 主工作区 + 辅助检查;
- 表格 + 行级预览。
只有存在阅读顺序依赖时才纵向堆叠。不要把短字段、操作区和预览全部纵向排列,制造不必要页面高度。
分栏需满足:
- 主区宽度高于辅区;
- 文本保持可读行长;
- 两栏分别只在确有独立浏览需求时滚动;
- 窄屏按任务顺序折叠为单列;
- 主操作在布局变化后仍保持稳定位置。
## 内容驱动尺寸
默认让内容、Flex/Grid 和父容器边界决定尺寸,不为当前页面实例写“刚好适配截图”的固定宽高。
优先使用:
- 内容固有尺寸;
- 可伸缩轨道和剩余空间分配;
- 最小值、最大值和比例约束;
- 明确的父容器边界;
- 必要时的纵横比。
紧凑控件按内容占用空间;搜索、正文、主工作区等明确需要扩展的区域才吸收剩余空间。不要让分页、状态、数量或短选择器因父级布局自动拉满。
高度默认由内容撑开。需要限制时设置最大高度并指定滚动区不通过固定高度制造空白。Flex/Grid 子项应允许在父级边界内收缩,避免长内容撑破页面。
只有以下情况才使用固定尺寸:
- 稳定点击区域或控件规格;
- 图标、头像、缩略图等共享视觉规格;
- 媒体比例;
- 虚拟化或几何计算依赖;
- 防止关键布局跳动;
- 视口安全边距。
固定尺寸必须说明保护的行为,并优先由共享组件、统一设计变量或布局规则负责。删除固定尺寸不会破坏行为时,改回内容驱动。
## 滚动由谁负责
每个表面默认只指定一个主滚动容器:
- 应用外壳固定时,让主内容区滚动;
- 普通页面由主内容区滚动;
- 弹窗由 Body 滚动;
- 表格仅在自身容器中横向滚动;
- 独立面板只有在用户确实需要分别浏览时才拥有内部滚动,并必须具有明确任务边界和尺寸边界。
所有滚动容器必须具有明确尺寸边界。Grid 或 Flex 子项需要 `min-height: 0` / `min-width: 0`,避免内容撑破父容器。
禁止:
- `body`、页面内容和弹窗同时滚动;
- 弹窗整体滚动导致标题和操作消失;
- 无尺寸上限的内容把弹窗推出视口;
- 页面整体出现水平滚动条;
- 为解决溢出直接添加 `overflow: auto`
- 多层嵌套滚动却没有独立任务边界。
## 弹窗结构
存在正文和操作的弹窗必须使用共享 Header / Body / Footer 三段式结构。
共享弹窗需要满足:
- 弹窗根容器使用“内容上限 + 动态视口边界”,不能依靠固定高度填满屏幕;
- Header 固定顶部,拥有标题、必要身份和关闭入口;
- Body 使用剩余空间并作为唯一纵向滚动区;
- Footer 固定底部,完整跨越弹窗内容宽度;
- Header 和 Footer 使用稳定边界及组件内间距;
- 使用弹窗的页面不得自行覆盖弹窗内部布局。
该差异应成为含义明确的共享组件变体,不使用页面专属样式类修补。
## 操作栏
弹窗存在保存、完成、确认或取消动作时:
- 所有完成当前弹窗任务的操作放入 Footer
- 主操作位于右侧并保持最高强调;
- 取消或返回紧邻主操作,使用次级样式;
- 危险确认与普通操作明确分隔;
- 提示、计数或校验摘要可放 Footer 左侧;
- Footer 不随 Body 滚动;
- 内容区按钮只处理局部内容,不承担完成整个弹窗的任务。
纯阅读详情没有提交动作时可以只保留关闭入口,不为形式完整强加 Footer。
## 承载方式:弹窗、抽屉与完整页面
先检查项目已有的表面组件和同类任务页面;既有用法符合当前任务和本规范时才沿用,否则依据以下因素修复或替换共享承载方式。
弹窗适合:
- 自包含的短任务:确认、简短表单、预览 + 配置;
- 任务有明确的完成边界,完成后回到原页面位置和对象。
- 宽度由内容复杂度决定:确认使用窄弹窗,常规表单使用中等宽度,预览 + 配置使用宽弹窗或双栏;不通过继续扩大弹窗承载已经符合完整页面条件的任务。
抽屉适合:
- 用户需要保持底层列表、表格或画布的位置和当前对象可见;
- 任务是对当前选中对象的补充查看或编辑,例如行详情、筛选面板、辅助配置;
- 内容以单向浏览或单侧编辑为主,不需要多区域并行。
完整页面或工作区适合:
- 多步骤、复杂创作、大量媒体或多层导航;
- 任务本身就是用户的主要目的地,而不是某个页面的附属动作;
- 内容需要两个以上主要滚动区,或用户需要频繁在多个区域间切换。
其他约束:
- 不在一个模态弹窗上继续叠加第二个模态弹窗;菜单、下拉和 tooltip 不计入模态层级。需要第二层完整任务时升级为抽屉或页面。
- 项目没有抽屉组件时,不为单次需求引入新表面;确有需要时先建共享组件再在页面使用。
- 承载方式确定后,关闭或返回必须回到原位置和原对象。
## 响应式
- 使用动态视口高度,避免移动端地址栏造成溢出。
- 保留视口安全边距。
- 双栏在宽度不足时改单列。
- 移动端 Footer 可堆叠或让主操作占满宽度,但仍固定在弹窗底部。
- 检查长名称、校验错误和移动端输入面板出现后是否溢出或遮挡操作。
## 审查问题
- 首屏是否能完成主要判断或动作?
- 是否在纵向堆叠本可并列的信息?
- 哪些区域按内容尺寸,哪些区域吸收剩余空间?
- 每个固定宽高保护了什么行为?
- 谁拥有页面的纵向滚动?
- 是否出现意外的第二层滚动?
- 弹窗 Header 和 Footer 是否始终可见?
- Footer 是否为弹窗直接结构,而非某个内容列的子元素?
- 操作按钮是否稳定出现在底部栏?
- 内容变长后是否只滚动 Body
- 宽表格是否只在自身容器横向滚动?
- 当前任务是否已经复杂到应该使用独立页面?