AI 编程之界面设计指导

目标:在使用 GitHub Copilot 或其他 AI 编程 Agent 开发界面时,建立一套可理解、可复用、可验证的 UI 设计规范,让 AI 在不同页面和不同会话中持续生成一致的产品体验。

一、核心结论

AI 不会因为看过一次设计稿,就永久记住产品风格。要让 AI 稳定遵守 UI 规范,必须把设计要求同时落实到五个层面:

设计原则
   ↓
Design Tokens
   ↓
可复用组件
   ↓
项目指令与 Agent 工作流
   ↓
自动化检查与视觉验证

其中,文档负责说明规则,Token 负责固定数值,组件负责承载交互模式,项目指令负责约束 Agent,自动化检查负责阻止偏离。

不要只对 Copilot 说“做得现代一点”“保持风格统一”。这类描述缺少可执行标准,AI 很容易在每个页面重新发明一套颜色、间距和组件。

二、设计规范的分层结构

建议新项目准备以下文件和目录:

项目根目录/
├── .github/
│   ├── copilot-instructions.md
│   └── agents/
│       └── ui-reviewer.agent.md
├── docs/
│   └── design-system.md
├── src/
│   ├── components/
│   │   └── ui/
│   ├── styles/
│   │   ├── tokens.css
│   │   └── globals.css
│   └── pages/
└── tests/
    └── visual/
层级 主要职责 典型内容
设计原则 统一产品气质和取舍方向 产品定位、视觉关键词、禁止事项
design-system.md 解释完整设计系统 色彩、字体、布局、状态、无障碍
Design Tokens 固化设计数值 颜色、字号、间距、圆角、阴影、断点
UI 组件 固化交互和视觉模式 Button、Input、Dialog、Table、Tabs
项目指令 约束 Agent 的开发行为 先搜索、优先复用、必须验证
自动化检查 防止代码偏离规范 lint、typecheck、视觉回归、a11y

这些层级不要重复维护同一份信息。例如,颜色的实际值应只定义在 Token 文件中,设计文档引用 Token 名称,项目指令要求使用 Token。

三、先定义设计方向

在开始实现页面前,先用一页文档回答以下问题:

3.1 产品定位

  • 主要用户是谁?
  • 用户是在高频操作、阅读内容,还是完成一次性任务?
  • 产品需要显得专业、可信、亲切、效率优先,还是具有探索感?
  • 哪些视觉风格明确不适合本产品?

3.2 视觉关键词

建议选择 3 到 5 个具体词,例如:

克制、清晰、温暖、信息密度适中、强调操作反馈

避免使用“高级”“现代”“好看”这类无法直接判断的词,除非同时给出颜色、字体、布局和组件示例。

3.3 设计禁区

明确告诉 AI 不要做什么,通常和“应该做什么”同样重要:

  • 不使用与产品定位不符的紫色渐变
  • 不为每个区域创建独立卡片
  • 不使用无意义的装饰性大图形
  • 不随意引入新的字体、颜色和圆角
  • 不用超大标题挤占首屏主要操作区域
  • 不为了视觉效果牺牲可读性、响应式布局或键盘操作

四、用 Design Tokens 固化视觉语言

Token 是 Copilot 最容易稳定复用的设计上下文。与其描述“适当的间距”,不如给出明确的 Token。

示例:

:root {
  --color-brand-500: #1464f4;
  --color-brand-600: #0f4dcc;
  --color-text-primary: #172033;
  --color-text-secondary: #667085;
  --color-surface: #ffffff;
  --color-surface-muted: #f4f6f8;
  --color-border: #d9dee7;
  --color-danger: #d92d20;
  --color-success: #14804a;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;

  --font-body: "Inter", sans-serif;
  --font-heading: "Manrope", sans-serif;
}

至少应定义以下类别:

  • 颜色:品牌色、文字色、背景色、边框色、状态色
  • 字体:字体族、字号、字重、行高
  • 间距:页面边距、组件内边距、表单间距、区域间距
  • 尺寸:容器最大宽度、控件高度、图标尺寸
  • 圆角与阴影:输入框、按钮、卡片、弹窗的层级关系
  • 断点:移动端、平板、桌面端的布局切换规则
  • 动效:持续时间、缓动曲线、允许使用的动效场景

项目规则应明确:

  • 业务组件不得直接写颜色、间距、圆角和阴影值
  • 新增 Token 前必须说明使用场景
  • 优先复用现有 Token,不为单个页面创建一次性数值
  • Token 改动必须检查受影响的组件和页面

五、用组件承载设计规范

Copilot 最可靠的复用对象是已经存在的代码,而不是一段抽象描述。因此应先建立基础 UI 组件,再让 AI 开发业务页面。

建议优先建设:

Button       IconButton       Input       FormField
Select       Checkbox         Switch      Dialog
Drawer       Toast            Badge       Card
Tabs         Table            Stack       Grid
Container    PageHeader       EmptyState  LoadingState

项目指令可以写成:

## UI 组件规则

- 实现页面前,先搜索 `src/components/ui/` 中是否已有可复用组件。
- 已有组件能够满足需求时,不创建相似的新组件。
- 业务页面优先使用 `Button`、`FormField`、`Dialog` 等项目组件。
- 不直接使用原生 `<button>`、`<input>` 替代已有组件,除非有明确技术原因。
- 新增公共组件时,必须包含默认、hover、focus、disabled、loading 和 error 状态。
- 新增公共组件时,补充使用示例和测试。

每个公共组件应包含:

  1. 清晰的组件名称和用途
  2. 稳定、尽量小的 API
  3. 所有重要视觉状态
  4. 键盘和屏幕阅读器行为
  5. 移动端行为
  6. 正确和错误使用示例
  7. 必要的单元测试或交互测试

六、建立项目级 Copilot 指令

.github/copilot-instructions.md 不应写成审美宣言,而应写成 Agent 可以直接执行的工作规则。

可以加入以下模板:

## UI 开发流程

实现任何新页面或组件前:

1. 阅读 `docs/design-system.md`。
2. 搜索 `src/components/ui/` 中的已有组件。
3. 找一个结构或业务场景相近的现有页面作为参考。
4. 列出准备复用的组件、Token 和布局模式。
5. 说明桌面端、平板端和移动端的布局方案。
6. 再开始修改文件。

## UI 一致性规则

- 优先复用现有组件和 Design Tokens。
- 禁止在业务组件中硬编码颜色、间距、圆角和阴影。
- 禁止为了单个页面引入新的字体或视觉主题。
- 不把每个页面区域都包成卡片。
- 不使用没有产品价值的装饰性图形。
- 图标按钮必须有可访问名称。
- 交互组件必须实现 hover、focus、disabled 和 loading 状态。
- 页面必须处理 loading、empty、error 和 success 状态。
- 长文本必须能够换行,页面不能产生非预期的横向滚动。

## 验证要求

- 修改 UI 后运行项目规定的 lint、typecheck 和测试命令。
- 公共组件变更后检查所有调用方。
- 关键页面必须进行桌面端和移动端浏览器验证。
- 发现现有设计系统无法满足需求时,先说明缺口,不要悄悄新增一套模式。

规则应尽量引用项目中的真实路径、组件名和命令。比起“遵守设计规范”,优先使用 src/components/ui/Button.tsx 更容易得到稳定结果。

七、让 Agent 先对齐,再编码

开发新页面时,推荐使用以下提示词:

请在当前项目中实现用户管理页面。

开始编码前请先:
1. 阅读 `docs/design-system.md`。
2. 检查 `src/components/ui/` 中已有的表格、按钮、表单和弹窗组件。
3. 找一个现有页面作为布局参考。
4. 列出准备复用的组件和 Design Tokens。
5. 说明桌面端和移动端的布局方案。

实现要求:
- 不创建与现有组件重复的 UI。
- 不直接写新的颜色、间距、圆角或阴影值。
- 覆盖 loading、empty、error 和 disabled 状态。
- 完成后运行 lint、typecheck 和相关测试。

这一步的目的不是增加形式,而是让 Agent 在实现前暴露它对设计系统的理解,便于及时纠正。

八、为界面状态建立统一规范

很多页面看起来不一致,并不是主视觉不一致,而是状态处理不一致。每个页面和公共组件都应明确:

状态 需要定义的内容
Loading 骨架屏、加载指示器、按钮是否禁用
Empty 空状态图形、说明文字、主要操作
Error 错误信息、重试操作、错误范围
Disabled 禁用颜色、鼠标行为、键盘行为
Success 成功反馈、Toast、页面状态更新
Validation 字段错误、提示位置、提交行为
Permission 无权限提示、隐藏还是禁用操作

不要让 Agent 在每个页面自行决定“加载中显示什么”。应提供 LoadingStateEmptyStateErrorState 等组件和对应示例。

九、响应式与可访问性必须成为设计规范的一部分

9.1 响应式规则

每个页面至少验证:

  • 小屏手机
  • 大屏手机或平板
  • 桌面端
  • 宽屏桌面端

同时明确:

  • 导航何时折叠
  • 表格如何转为卡片或横向滚动
  • 弹窗如何适配窄屏
  • 表单如何从多列变为单列
  • 长标题和长按钮文字如何换行
  • 图片和图表如何保持比例

9.2 可访问性规则

应把以下要求写入项目指令,而不是等最后再补:

  • 交互元素必须可通过键盘访问
  • 必须保留清晰的 focus 状态
  • 图标按钮必须有 aria-label 或可见文字
  • 表单字段必须关联 label 和错误提示
  • 颜色不能作为表达状态的唯一方式
  • 文字与背景满足项目规定的对比度
  • 弹窗打开后焦点进入弹窗,关闭后恢复原焦点
  • 动效应尊重用户的减少动态偏好

十、用自动化检查防止规范漂移

项目指令只能影响 Agent 的行为,不能代替工程约束。建议加入:

  • ESLint:禁止重复组件、限制原生控件或硬编码样式
  • Stylelint:统一 CSS 写法
  • TypeScript:限制组件属性和 Token 使用
  • Storybook:集中展示组件及其状态
  • Playwright:验证关键用户流程和响应式行为
  • axe-core:检查基础可访问性
  • Chromatic、Percy 或截图对比:检查视觉回归

例如,下面这种代码应被检查规则阻止:

color: #1464f4;
margin: 17px;
border-radius: 13px;

应改为:

color: var(--color-brand-500);
margin: var(--space-4);
border-radius: var(--radius-md);

视觉验证不需要覆盖所有页面。优先选择登录、首页、核心列表、核心表单、弹窗和移动端主流程。

十一、设置 UI 审查 Agent

当项目需要反复开发页面时,可以创建一个专门的 UI 审查 Agent,负责发现偏离,而不是负责重新设计产品。

示例:

---
name: ui-reviewer
description: 审查界面是否符合项目设计系统和可访问性要求
---

# UI 审查职责

审查变更是否符合:

- Design Tokens 使用规范
- 公共组件复用规范
- 字体、颜色、间距、圆角和阴影规范
- 响应式布局规范
- loading、empty、error 和 disabled 状态
- 键盘操作和可访问性
- 现有页面的视觉一致性

审查步骤:

1. 阅读 `docs/design-system.md`。
2. 对比 `src/components/ui/` 中的已有组件。
3. 检查硬编码样式和重复组件。
4. 检查移动端布局和文本溢出。
5. 检查交互状态和可访问性。
6. 按严重程度列出问题、文件和修复建议。
7. 没有问题时,明确说明测试覆盖范围和剩余风险。

除非用户明确要求,不直接修改文件。

推荐的工作流是:

需求分析
   ↓
设计系统对齐
   ↓
实现 Agent 编码
   ↓
lint / typecheck / 测试
   ↓
浏览器和视觉验证
   ↓
UI Review Agent 审查
   ↓
修复并重新验证

十二、新项目的最小落地清单

如果项目刚开始,不必一次建设完整设计平台,但至少完成以下工作:

  • 写出产品定位、3 到 5 个视觉关键词和设计禁区
  • 定义颜色、字体、间距、圆角、阴影和响应式断点
  • 创建 tokens.css 或等价的 Token 文件
  • 实现 Button、Input、FormField、Dialog、Card、Table 等基础组件
  • 制作一个真实业务页面作为参考页面
  • 在项目指令中规定“先搜索、优先复用、缺口先说明”
  • 统一 loading、empty、error、success 和 disabled 状态
  • 加入 lint、typecheck 和基础可访问性检查
  • 对关键页面执行桌面端和移动端验证
  • 每次新增公共组件都补充示例和测试

十三、推荐的首轮提示词

我要从零创建一个 [技术栈] 项目,目标是 [一句话描述]。

请先完成 UI 设计系统初始化,不要立即开发全部业务页面:
1. 确认目标用户、核心任务和产品气质。
2. 提出颜色、字体、间距、圆角、阴影和响应式断点方案。
3. 生成 `docs/design-system.md` 和 Design Tokens。
4. 创建基础 UI 组件,并为每个组件覆盖主要交互状态。
5. 创建一个真实业务页面,作为后续开发的参考实现。
6. 更新 `.github/copilot-instructions.md`,写入 UI 复用和验证规则。
7. 配置 lint、typecheck、可访问性和必要的视觉验证。

每一步先说明发现、假设、产出和验证方式。遇到产品定位、品牌色或字体等关键决策不明确时,先暂停询问。

十四、最终原则

让 AI 坚持一套界面设计规范,依靠的不是一条神奇提示词,而是一套工程化约束:

文档说明原则
    +
Token 固化数值
    +
组件承载模式
    +
指令约束行为
    +
自动化验证结果
    =
可持续的一致性

优先级可以这样理解:

实际组件和现有代码
    > Design Tokens
    > 自动化检查
    > 项目指令
    > 自然语言描述

因此,最有效的策略不是不断提醒 Copilot“保持一致”,而是让正确的实现方式成为项目中最容易找到、最容易复用、也最容易通过检查的方式。