Files
planet/docs/technical/frontend-layout-guidelines.md
2026-04-21 22:49:39 +08:00

310 lines
8.6 KiB
Markdown
Raw 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.
# Frontend Layout Guidelines
本项目后台页面默认遵循“单屏工作区”布局规范。目标不是让页面永远不溢出,而是确保在常见桌面视口下:
- 页面主结构能在一屏内看清
- 用户能同时看到页头、摘要区和主工作区
- 超出的内容在模块内部滚动,而不是把整页纵向撑爆
当前推荐参考实现:
- [frontend/src/pages/BGP/BGP.tsx](/home/ray/dev/linkong/planet/frontend/src/pages/BGP/BGP.tsx)
- [frontend/src/index.css](/home/ray/dev/linkong/planet/frontend/src/index.css)
## 核心原则
### 1. 页面优先保证一屏工作区
管理页默认采用:
- 页头:标题、说明、主要操作
- 主工作区:统计卡、表格、图表、列表、标签页
推荐结构:
```tsx
<AppLayout>
<div className="page-shell">
<div className="page-shell__header">...</div>
<div className="page-shell__body">...</div>
</div>
</AppLayout>
```
页面总高度应被限制在 `AppLayout` 内容区内,而不是继续让整个页面自然向下增长。
### 2. 滚动优先发生在模块内部
如果表格、日志、长列表、图表明细超出空间:
- 让卡片内部滚动
- 让表格内部滚动
- 让标签页内容区内部滚动
不要默认依赖整个页面滚动去“解决”空间问题。
### 3. 主工作区必须拿到主要空间
页面里最重要的模块必须是视觉和空间上的主角。通常应保证:
- 页头始终可见
- 摘要区高度被控制
- 主表格 / 主图表 / 主分析区占据 50% 以上可视高度
如果一个页面有多个大模块,优先顺序是:
1. 先压缩说明区和摘要区
2. 再把次级模块收进标签页或切换视图
3. 最后才考虑继续增加整页滚动
### 4. 小屏幕和高缩放必须进入紧凑模式
在窗口高度较低、宽度较窄、或系统缩放较高时,应主动切换紧凑布局,例如:
- 缩小卡片 padding
- 缩小表头和单元格间距
- 将摘要区改为更紧凑的单行/横向滚动布局
- 将次级模块移入标签页、抽屉、折叠区
紧凑模式的目标是保持可用,不是单纯把文字和控件一股脑缩小。
### 5. overflow 责任必须明确
页面中的大块内容必须明确:
- 谁负责占满剩余高度
- 谁负责裁剪
- 谁负责滚动
常见要求:
- 父容器链路需要 `min-height: 0`
- 工作区容器通常需要 `display: flex`
- 真正的滚动节点要显式 `overflow: auto`
### 6. 卡片不能被压到不可读
历史上我们反复踩到的问题不是“没有滚动条”,而是:
- 卡片被 `flex` 压缩得只剩一小条可视区域
- 文字能渲染,但读不完整
- 内容其实存在,却被 `overflow: hidden` 裁掉
因此后续约束是:
- 先保证卡片有可读的最小高度
- 如果继续压缩会影响阅读,就切换成内部滚动
- 不要为了“保持一屏”而把正文、表格、描述区压成无法阅读的条状区域
### 7. Tabs 不是天然安全的布局容器
历史上 Tabs 相关回归非常多,典型问题包括:
- 隐藏 tab pane 因为自定义 `display: flex` 而重新露出来
- 所有 tab 被强行套用同一套高度/overflow 规则
- 表格 tab 能工作,但 markdown / help / diagnostics tab 被压坏
因此约束是:
- `Tabs` 里的每类内容都要单独定义自己的布局策略
- 表格 tab 可以是“固定高度 + 内部滚动”
- 文档/Markdown tab 更适合“tab pane 自身滚动 + 内容正常文档流”
- 如果覆盖组件库样式,必须同时检查 hidden 状态是否仍然成立
### 8. 摘要区优先进入紧凑模式,而不是挤压正文
历史经验表明,最容易被误处理的是顶部摘要卡:
- 它们经常为了“都放下”被强行压窄
- 然后正文、表格、AI 结果区一起失去主空间
后续统一约束:
- 小屏或高缩放时,摘要卡优先:
- 降低 padding
- 改成横向滚动
- 改成更紧凑的网格
- 不要优先牺牲主工作区的可视面积
### 9. 长文档类内容优先保证阅读体验
像下面这些内容,不能直接套用“表格工作区”的逻辑:
- AI 简报
- 运行日志
- 原始 JSON
- 帮助说明
- 多段描述性文本
这些区域应该优先满足:
- 标题和元信息稳定可见
- 正文有明确的最小可读高度
- 正文滚动策略单独定义
- 支持 Markdown 表格、分隔线、引用、代码块等结构
### 10. 高度关键路径要少包一层
历史上不少滚动问题不是组件本身错,而是多包了一层之后:
- 高度链路断掉
- `min-height: 0` 没传下去
- `overflow` 责任被吃掉
因此:
- 对高度关键区域,优先使用最直接的 DOM 结构
- 使用 `Space`、额外包装 `div`、第三方布局容器时,要确认它们不会改变滚动和高度语义
- 如果一个区域已经出现“内容明明有,但只剩一条缝”,优先怀疑中间包装层
## 历史坑位总结
从 Earth、Playground、BGP、DataSources 这些页面的 bugfix 可以归纳出几类高频坑:
### 1. 用 `overflow: hidden` 掩盖布局问题
表面上看页面“整齐了”,实际上会导致:
- 内容被裁掉
- tab 内容只剩一条缝
- 面板明明渲染成功,但用户看不见
正确做法:
- 让真正的内容节点滚动
- 不要让上层容器无差别裁剪所有子内容
### 2. 把所有 tab 当成同一种内容
表格、Markdown、帮助卡、日志流的空间需求完全不同。
正确做法:
- 表格:固定工作区 + 内部滚动
- 文档:普通流式内容 + pane 级滚动
- 侧边说明:内容驱动高度,不强行拉满
### 3. 只做视觉缩小,不做空间重分配
这会导致:
- 卡片文字被截断
- 表格只剩 1 到 2 行
- 按钮和筛选区挤成一团
正确做法:
- 紧凑模式优先重排
- 横向滚动摘要区
- 折叠/收纳次级模块
### 4. 父容器高度链不完整
这是最常见的内部滚动失效原因。
检查顺序:
1. 外层是否真的有确定高度
2. flex 父容器是否带了 `min-height: 0`
3. 真正滚动节点是否明确 `overflow: auto`
4. 中间包装层是否偷偷改了布局语义
### 5. UI 状态和显示状态不同步
Earth 相关改动里反复出现:
- 图层隐藏了,但 hover/lock 还在
- tooltip 还在显示旧对象
- legend 没跟着切换
这类约束同样适用于后台页面:
- 被隐藏、卸载、切换出视图的内容,不应继续保留活跃交互状态
## 推荐实现模式
### 页面骨架
优先复用项目里已有的通用结构:
- `.dashboard-content-inner`
- `.page-shell`
- `.page-shell__header`
- `.page-shell__body`
- `.table-scroll-region`
不要每个页面都重新发明一套完全不同的高度和滚动语义。
### 表格工作区
推荐模式:
```tsx
<Card>
<div className="table-scroll-region" ref={tableRegionRef}>
<Table
pagination={false}
scroll={{ x: 1200, y: tableHeight }}
/>
</div>
</Card>
```
要求:
- 表格尽量在卡片内部滚动
- `scroll.y` 应来自实际可用高度估算,而不是完全静态的魔法数字
- 父容器链路要保证 header、body、content 的 overflow 都在表格内部闭合
### 多模块页面
如果一个页面同时有:
- 摘要卡
- 表格
- 异常明细
- 最近事件
不建议简单纵向堆叠全部模块。优先使用:
- 顶部摘要 + 底部单一主工作区
- 标签页切换多个次级数据视图
- 左右分栏,并保证每栏内部独立滚动
## 不推荐的做法
以下模式默认视为不符合本项目页面规范:
- 依赖整页纵向滚动来显示主要工作区
- 一个页面纵向堆 3 到 4 个大卡片,每个都想完整展示
- 表格没有内部滚动,导致缩放后只能看到 1 到 2 行数据
- 父容器缺少 `min-height: 0`,导致内部滚动失效
- 只做视觉缩小,不处理真正的空间分配
## 页面验收检查清单
提交前至少检查:
- 页头、摘要区、主工作区能否同时出现
- 主工作区是否拿到了页面中最多的高度
- 表格或明细溢出时,滚动条是否出现在模块内部
- 卡片是否被压缩到文字显示不完整;如果会,是否已经切换为内部滚动
- 浏览器缩放到 `125%` / `150%` 时是否仍可用
- 低高度窗口下是否还保有合理的可见内容行数
- Tabs、Card、Table 在 overflow 时是否仍可操作
- 非表格 tabMarkdown、帮助说明、日志是否有独立且合理的滚动策略
## 落地顺序
后续新增或重构后台页时,优先按这个顺序设计:
1. 先定义主工作区
2. 再确定哪些模块必须常驻可见
3. 最后再做样式和视觉层次
简单说:
- 先保证空间分配正确
- 再处理滚动边界
- 最后再做美化