Product UI
一个应用程序是一个工作表面:人们反复回来完成一项任务。每个元素通过服务于该任务来赢得其位置。目标是赢得熟悉度——熟悉这类工具的人看到控件就能信任,界面融入任务之中。
这些规则适用于任何应用程序。特定于某个项目的内容——设备目标、设计系统、组件、方向、已知偏差——存在于项目文件中;请从中构建。在调用屏幕完成之前,运行review.md。
项目文件
按以下顺序查找:CLAUDE.md或AGENTS.md中命名的路径,然后是.claude/product-ui.md。当不存在时,在第一次构建之前从templates/project.md创建.claude/product-ui.md:
- 找到设计系统:令牌文件(CSS自定义属性、Tailwind主题、令牌JSON)、组件库(仓库内的
components/ui、shadcn、MUI、Radix等)、故事文件。 - 列出屏幕需要的构建块(页面脚手架、表格、表单字段、空状态、对话框、Toast等)及其路径。将每个缺失的标记为缺失;切勿凭空编造路径。
- 记录你在途中发现的偏差:代码违反以下规则的地方。
- 询问用户每个应用的设备目标以及视觉语言的所有者(设计团队或开发者)。根据应用的意图建议目标。
只写你验证过的内容。将CLAUDE.md指向该文件,以便后续会话能找到它。
当项目没有视觉方向且表面不应看起来通用时,首先运行design-direction技能;它会将结果记录在同一文件中。
目的优先
在布局之前,每项各写一行:
- 屏幕服务的任务以及执行该任务的人;
- 第一眼阅读:屏幕打开时他们看的第一件事;
- 主要操作以及他们重复操作的频率;
- 目标设备:手机、平板、笔记本电脑、大屏幕,来自项目文件。
屏幕上的每个区域都映射到这些行之一。不映射到任何行的区域将被删除。
真实内容
使用类似生产环境的内容进行构建和评估:真实长度的真实姓名、最长的合理标题、0、1、7和500个项目、缺失的可选值、比英语长30%的翻译。"张三"、"ACME公司"、"Lorem ipsum"、"项目1"和整数会隐藏所有布局问题,并且是使屏幕看起来像生成内容的首要因素。当领域的数据未知时,询问样本或从模式中推导。
每种尺寸
屏幕针对其主要设备进行优化,并在其他所有断点处使用相同功能。每种尺寸获得适合其模式的模式,而不是桌面版的压缩副本:侧边栏变成抽屉或图标导轨,表格变成堆叠列表,拆分窗格变成带有后退步骤的页面,悬停变成可见控件,密集工具栏变成溢出菜单。在断点以下消失的功能是一个发现。
在目标宽度处,任何内容都不会水平滚动:页面不会,列表在其自身容器内也不会。自由文本列(名称、标题、电子邮件、文件名)在悬停时收缩并截断,并显示完整文本;只有真正宽的网格(矩阵、时间线)可以滚动,并且会明确说明。
在大显示器上,内容保持可读的度量:文本块每行保持在约75个字符以下,表单保持其列宽,表格可以增长,而其自由文本列占用空间。
导航
- 全局导航列出应用的各个部分,并在每个屏幕上保持不变。
- 具有自己子区域的部分可以添加一个本地层(第二列或标签)。每一层只显示自己的级别:没有层重复另一个层的条目,并且两个条目从不共享标签。
- 作用域——屏幕操作的哪个组织、工作区或账户——由切换器设置,显示一次。
- 每个页面距离全局导航最多两个选择,并且本地导航在主设备上保持可见。
- 第一个控件上方的Chrome保持较小:面包屑永不重复其下方的页面标题。
- 具有多个部分或许多记录的应用提供四处跳转搜索(⌘K / Ctrl+K),通过名称或粘贴的ID查找页面和记录。
密度
-
一次性显示工作集。人们扫描或比较的列表是一个表格,每个项目一行;卡片网格适用于少数项目,其图片或预览是内容。
-
行高跟随内容:单行行高36–44px,带有第二行或缩略图的行最多64px;内边距从不占用比内容更多的高度。
-
相关项目之间的间隙小于组之间的间隙,因此仅通过间距就可以读取分组。
-
行中的每个元素都赢得其位置。测试每个元素:
- 任务:它服务于查找、比较、打开或操作项目,针对此屏幕的任务;
- 删除:删除它会丢失某人需要的东西;否则它将被移除,或移到详细信息视图;
- 冗余:它不重复任何列、活动过滤器或页面标题;
- 自解释:无需悬停、工具提示或图例即可读懂,状态是文字,绝不仅仅是颜色;
- 顺序:首先标识项目,然后是人们比较的事实,最后是操作。
缺失的事实也是一个发现:当人们反复打开项目以比较一个值时,该值应属于行中。
-
默认每行一行。次要事实位于其自己的列或淡化的第二行中,绝不放在必须悬停才能比较的工具提示中。
-
标题、描述和帮助文本尽可能简短,以完成任务。重复标题的页面描述将被删除。
-
空白分隔组;它从不填充稀疏的屏幕使其看起来满。
-
盒子(边框、背景、阴影)标记人们作为整体操作的事物。仅分组使用空格或分隔线完成;卡片内的卡片是一个发现。
层级结构
- 每个视图一个主要操作,视觉上主要,位于其作用域的右上角(页面标题或面板标题)。次要操作为轮廓或幽灵样式;破坏性操作放在最后。
- 每个尺寸、空间、颜色和半径都来自表面的设计系统,并保持在其内部。任意值(
text-[10px]、p-[13px]、原始十六进制)是一个发现;修复方法是使用最近的步骤,或者当没有步骤合适时创建新令牌。 - 权重和颜色在大小之前承载层级结构。
- 颜色承载含义:强调色标记主要操作、选择和状态。状态色仅出现在存在状态的地方。
- 图标伴随标签,在它们加速识别的地方(导航、频繁操作)使用,并且仅对通用操作(关闭、搜索、更多)独立使用,带有可访问名称。每个按钮、标题或卡片上的图标是装饰。
- 只读值渲染为文本,而不是输入。
- 查看者角色无法使用的控件被隐藏,由服务器检查的相同能力决定。当知道操作存在很重要时,它显示为禁用状态并提供原因("只有管理员可以邀请")。
- 文案命名人们识别的内容,而不是其背后的基础设施:不提及供应商或管道名称,除非受众直接使用它们。导航中不列出未构建或已关闭的功能。
文案
界面文本是设计的一部分,也是最容易暴露生成屏幕的特征。
- 按钮说明其作用,作为动词及其宾语:"邀请成员"、"导出CSV"。在应用内部绝不用"提交"、"确定"、"点击此处"、"开始使用"。
- 确认按钮重复问题中的动词:"删除3个文件?" → "删除文件"。
- 每个标签、标题和按钮使用句子大小写。没有感叹号,没有"哎呀",没有"成功",没有"请"。
- 反馈以用户的语言说明结果:"发票已发送至finance@…",而不是"操作已成功完成"。
- 空状态说明属于此处的内容以及如何到达此处,用一两句简单的句子。没有机智话语,没有插图填充,没有"这里没什么可看的"。
- 工具内部没有营销语气:删除"无缝"、"轻松"、"强大"、"解锁"、"超级充电"、"魔法"、"AI驱动"以及任何赞美产品的句子。
- 整个应用每个概念一个术语;术语表存在于项目文件中。
- 数字、日期和单位在应用内遵循一种格式;计数使用正确的复数形式("1个文件"、"2个文件")。
列表和表格
- 数字右对齐,使用
tabular-nums;文本左对齐。 - 时间戳在应用内使用一种固定格式,绝不使用浏览器的区域设置默认值,并且绝不截断。监控屏幕将相对时间("3分钟前")与悬停时的绝对时间配对,反之亦然。
- 标题用一两个词命名列;可排序的标题在单击时排序。
- 搜索、过滤器、排序、页面和打开的项目存在于URL中,因此视图可以经受重新加载、后退和共享链接。
- 行是到其项目的真实链接:整行打开它,Cmd+单击打开新标签页。
- 行中的每个引用——人、组织、任务、ID——链接到其自己的页面。
- 每行操作位于行末尾的稳定列中,在静止时可见;至少在触摸屏上显示。在不可见时消耗点击的控件是一个Bug。
- 批量工作需要选择复选框、全选和批量操作栏,用于用户批量处理项目时。
- 超过约50行时分页或窗口化;计数始终可见。限定集合的过滤器(月范围)在显示边界时替代分页。
- 过滤器标签可以携带计数;然后它们兼作页面的摘要。
表单
- 标签位于字段上方,一列,按用户思考数据的顺序排列。
- 在失去焦点时和提交时验证;错误位于其字段下方,并说明如何修复。
- 默认值是最常见的答案。可选字段标记为可选,必填字段不标记。
- 创建或操作表单上的提交保持启用。提交无效输入聚焦第一个无效字段,并在该字段下方显示如何修复。
- 编辑表单上的保存可能保持禁用,直到有内容更改,因为没有等待保存的内容;一旦有任何更改,它就会启用,上述规则适用,并且旁边的"未保存的更改"提示显示状态。
- 每个视图一次保存。离开未保存的更改时先询问。
- 当其自身操作挂起时,控件被禁用,因此不能触发两次。
- 短表单或单个字段内联编辑;对话框用于不得丢失上下文的聚焦任务。
- 输入使用正确的类型和
autocomplete(电子邮件、电话、一次性代码等),以便手机显示正确的键盘,浏览器自动填充。 - 文件上传触发器是一个可聚焦的按钮,打开文件选择器,也接受拖放。
- 配置另一个表面绘制内容的页面(入职流程、品牌、模板)在其设置旁边显示该表面的预览。
操作和反馈
- 具有返回路径的操作(恢复、取消归档、重新激活)立即运行并提供撤销,无需额外的确认。切换本身就是撤销,只需要即时反馈。
- 没有返回路径的操作需要确认,说明会丢失什么("删除3个文档")。看起来可逆但实际上没有逆操作的操作被视为不可逆,直到逆操作存在。
- 每个操作在100毫秒内响应:乐观更新、控件上的挂起状态、或内容将放置位置的骨架屏。
- 需要几秒钟以上的工作在后台运行,并显示可见的进度,且能承受导航。
- 错误说明发生了什么以及接下来该做什么,位于发生位置旁边。
状态矩阵
每个视图都提供其所有状态,经过设计而非默认:
| 状态 | 形状 |
|---|---|
| 加载中 | 内容将占据的布局中的骨架屏 |
| 空 | 说明属于此处的内容并提供添加操作 |
| 过滤空 | 说明过滤器没有匹配任何内容并提供清除过滤器的选项 |
| 部分 | 加载的部分渲染;失败的部分显示其自己的错误,绝不显示为零 |
| 无权限 | 说明谁可以看到此内容以及如何获得访问权限,并提供前进的方法 |
| 错误 | 失败的内容、重试按钮、屏幕其余部分仍然可用 |
| 满 | 实际内容以真实数量呈现,包括长名称和多行 |
每个交互控件都有默认、悬停、焦点可见、活动、禁用和挂起状态。
在仪表板上,每个磁贴和图表拥有自己的状态:失败的读取显示其自己的错误,绝不显示为零或空图表。仪表板打开时关注需要关注的内容,而不是一行指标卡片;数字只与使其有意义的比较(目标、上一周期)以及团队达成一致的定义一起出现。图表在安装了dataviz技能时遵循该技能。
可访问性和主题
- 正文文本在每个主题中满足4.5:1对比度,大文本和控件边界为3:1。灰色上的淡灰色是最常见的失败。
- 焦点始终可见且从不被裁剪;焦点环是设计的,而不是移除浏览器默认值。
- 每个控件都有可访问名称;仅图标按钮获得
aria-label。地标(nav、main)和每个页面一个h1。 - 文本可调整大小至200%,布局保持不变。
- 当应用支持深色主题时,它是经过设计的:其自己的表面层次和重新调整的强调色,而不是反转颜色。在两个主题中审查每个屏幕。
人机工程学
- 主要任务可通过键盘完成:Tab顺序遵循阅读顺序,Enter提交,Escape关闭,焦点返回来源处。
- 点击目标至少24×24像素,频繁的更大,触摸屏上44像素;点击区域覆盖整行或标签,而不仅仅是图标。
- 频繁操作靠近其操作的对象。