Vercel界面设计指南
Rauno 两年前在 GitHub 上分享的 Web 界面指南,现在结合了 Vercel 的工程师与设计师的经验,发布了全新的版本。它提供了一系列关于如何设计高质量、易用且性能良好的 Web 界面的建议和最佳实践。
最佳实践,你需要通过在项目中维护 AGENTS.md 文件来确保生成的界面符合这些指南。 原文
交互
键盘可访问所有功能。 所有操作都应可用键盘完成,并遵循 WAI-ARIA Authoring Patterns。
清晰的焦点指示。 每个可聚焦元素都要有可见的焦点样式。优先使用
:focus-visible而非:focus,避免干扰鼠标用户;对控件分组使用:focus-within。管理焦点。 需要时使用焦点陷阱,并按 WAI-ARIA 规范移动与归还焦点。
视觉目标与点击目标一致。 如视觉元素小于 24px,应将可点击区域扩展到 ≥ 24px;移动端最小 44px。
移动端输入框尺寸。
<input>在移动端字体 ≥ 16px,避免 iOS Safari 聚焦时的自动缩放/平移;或设置<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />。尊重缩放功能。 不要禁用浏览器缩放。
水合安全的输入框。 水合(hydration)后输入框不应丢失焦点或当前值。
不要阻止粘贴。 不要在
<input>或<textarea>禁用粘贴。按钮的加载态。 显示加载指示器,同时保留原按钮文案。
加载态的最短显示时长。 使用旋转器/骨架屏时,加入短暂显示延迟(约 150–300ms)和最短可见时间(约 300–500ms),避免快速返回时闪烁。React 的
<Suspense>已内置类似机制。URL 即状态。 将状态持久化到 URL,确保分享、刷新、前进/后退都能正确工作(如使用 nuqs 管理查询参数)。
乐观更新。 成功概率高时先行更新 UI,并与服务端结果对账;失败时给出错误提示并回滚或提供撤销。
省略号表示后续输入。 需要进一步输入的菜单项(如“重命名…”)用省略号结尾。
确认破坏性操作。 需要确认,或提供带缓冲时间的撤销。
避免控件双击触发缩放。 设置
touch-action: manipulation。点击高亮按设计控制。 设置
-webkit-tap-highlight-color。交互要有容错性。 宽松的点击目标、清晰的可用性暗示、可预测的行为,降低误操作(如利用“预测锥”概念)。
工具提示时机。 组内第一个工具提示延迟显示;同组后续提示不延迟。
过度滚动处理。 在模态/抽屉等场景有意设置
overscroll-behavior: contain。滚动位置持久化。 前进/后退应恢复上次滚动位置。
合适的自动聚焦。 桌面端如只有一个主要输入项可自动聚焦;移动端尽量少自动聚焦,以免键盘弹出导致布局抖动。
无“死区”。 看起来可交互的区域就应可交互,不要让用户猜哪里能点。
一切都能深链接。 过滤器、标签页、分页、展开面板等(凡是用到 useState 的地方)都应可通过 URL 定位。
干净的拖拽体验。 拖拽时禁用文本选择,并对不应交互的元素应用
inert,避免选择/悬停与拖拽竞争。链接就用链接。 导航使用
<a>或<Link>,保证浏览器默认行为(Cmd/Ctrl + 点击、中键、右键新标签)可用;不要用<button>或<div>代替导航。宣告异步更新。 提示与内联校验使用礼貌级别的
aria-live。本地化键盘快捷键。 适配非 QWERTY 布局;显示平台特定符号。
动画
尊重
prefers-reduced-motion。 提供减少动效的替代方案。实现优先级。 能用 CSS 就不用主线程 JS。
优先级: CSS > Web Animations API > JS 动画库(如 motion)。
合成器友好。 优先动画
transform、opacity等 GPU 加速属性,避免触发布局/重绘(如width、height、top、left)。确有其必要。 只在有明确因果或能带来有意的愉悦时使用动画。
合适的缓动。 根据变化的尺寸、距离、触发方式选择缓动曲线。
可中断。 用户输入应能取消动画。
输入驱动。 避免自动播放;以用户操作为触发。
正确的变换原点。 让运动从“物理上合理”的位置出发。
不要用
transition: all。 明确列出要过渡的属性(通常是opacity、transform)。all容易让影响布局的属性参与动画而卡顿。跨浏览器的 SVG 变换。 将 CSS 变换/动画作用在
<g>包裹上,并设置transform-box: fill-box; transform-origin: center;。Safari 曾在 SVG 的 transform-origin 上有兼容问题,分组可避免原点计算错误。
布局
光学对齐。 当观感优先于几何准确时,可做 ±1px 的微调。
有意对齐。 每个元素都要有对齐依据:网格、基线、边缘或光学中心,不要“随便放”。
文本与图标的均衡。 并排时通过粗细、大小、间距或颜色让它们不打架。比如细线图标放在中等字重文本旁可能需要加粗描边。
响应式覆盖。 在手机、笔记本与超宽屏上验证;模拟超宽屏可把页面缩放到 50% 观察。
尊重安全区域。 使用安全区域变量,照顾刘海与系统内边距。
没有多余滚动条。 只渲染必要的滚动;修复溢出避免冗余滚动条。可在 macOS 开启“始终显示滚动条”来模拟 Windows 体验。
让浏览器做布局。 优先用 flex/grid/内在尺寸,避免 JS 测量;减少抖动,让 CSS 处理流动、换行与对齐。
内容
内联帮助优先。 优先用内联说明;工具提示作为最后手段。
稳定的骨架屏。 骨架应尽量镜像最终内容,避免布局位移。
准确的页面标题。
<title>要反映当前上下文。没有死胡同。 每个界面都提供下一步或返回路径。
设计所有状态。 空、稀疏、密集与错误态都要覆盖。
排版引号。 优先用弯引号(“ ”),而非直引号(" ").
避免孤行寡行。 控制断行与对齐,让段落边缘自然整洁。
比较用等宽数字。 使用
font-variant-numeric: tabular-nums或等宽字体(如 Geist Mono)。冗余信号。 不要只靠颜色表达状态,需同时给出文本标签。
图标要有标签。 为视障用户提供等价文字。
没有“仅展示”模式。 视觉上可省略标签,但必须保留可访问的名称/标签供辅助技术使用。
使用省略号字符。 用
…而不是三个点...。锚定标题。 章节链接时为标题设置合适的
scroll-margin-top。适应用户生成内容。 布局能兼容很短、一般、很长的内容。
区域感知格式。 按用户区域格式化日期、时间、数字、分隔符与货币。
语言优先于位置。 通过 Accept-Language 与
navigator.languages检测语言;不要用 IP/GPS 判断语言。可访问的内容。 准确命名(
aria-label)、隐藏装饰元素(aria-hidden),并在可访问性树中核验。仅图标按钮需要命名。 提供清晰的
aria-label。语义优先于 ARIA。 优先用原生元素(
button、a、label、table)而非堆砌aria-*。标题与跳过链接。 合理分层的
<h1–h6>与“跳转到内容”的跳过链接。从徽标直达品牌资产。 支持在导航徽标上右键快速访问品牌资源。
用不换行空格粘连术语。 用
把单位、快捷键、名称连在一起:10 MB → 10 MB,⌘ + K → ⌘ + K,Vercel SDK → Vercel SDK。无空格粘连可用⁠。
表单
回车即可提交。 文本输入聚焦时,回车提交表单。
文本区域的回车规则。 在
<textarea>中:⌘/⌃ + 回车提交,回车换行。处处有标签。 每个控件都有
<label>,或能与标签关联以供辅助技术使用。标签可激活。 点击
<label>应聚焦到关联控件。提交约束。 提交前按钮保持可用;发起请求后禁用按钮、显示加载指示,并包含幂等键。
不要阻止输入。 即便字段只接受数字,也允许自由输入并给出校验反馈;屏蔽按键会让用户摸不着头脑。
不要预先禁用提交。 允许提交不完整表单,以便显示校验反馈。
控件无“死区”。 复选框/单选与其标签应共享一个宽松的点击目标。
错误就近显示。 把错误显示在字段旁;提交时把焦点移到第一个错误上。
自动完成与 name。 设置正确的
autocomplete与有意义的name,启用自动填充。有选择地关闭拼写检查。 对邮箱、代码、用户名等禁用拼写检查。
正确的类型与输入模式。 选择合适的
type与inputmode,获得更好的键盘与校验体验。占位符表达“空”。 用省略号结尾。
占位符示例值。 占位符应是示例或模式,如 +1 (123) 456-7890、sk-012345679…。
未保存更改。 可能丢失数据时,在导航前警告。
密码管理器与 2FA。 确保兼容,并允许粘贴一次性验证码。
避免误触发密码管理器。 非认证字段(如“搜索”)避免使用保留名称(如 password),用
autocomplete="off"或 OTP 专用的autocomplete="one-time-code"。文本替换/扩展处理。 某些输入法会加尾随空格;提交前应修剪,避免莫名其妙的错误。
Windows 的
<select>背景。 原生<select>要明确设置background-color与color,避免 Windows 深色模式下对比不够。
性能
设备/浏览器矩阵。 记得测试 iOS 低电量模式与 macOS Safari。
可靠的测量。 禁用会加开销或改变运行时行为的浏览器扩展。
跟踪重渲染。 尽量减少并加速重渲染;用 React DevTools 或 React Scan。
分析时节流。 进行 CPU 与网络节流测试。
减少布局工作。 读/写合批,避免不必要的回流/重绘。
网络时延预算。
POST/PATCH/DELETE争取 500ms 内完成。按键开销。 优先使用非受控输入;让受控输入的更新闭环足够低开销。
大列表。 虚拟化(如 virtua)或用
content-visibility: auto。审慎预加载。 只预加载首屏图;其余延迟加载。
图像不引发 CLS。 明确指定图像尺寸并预留空间。
预连接外部源。 对资产/CDN 域使用
<link rel="preconnect">(需要时加crossorigin),减少 DNS/TLS 往返。预加载字体。 关键文本预加载字体,避免闪烁与位移。
字体子集化。 通过
unicode-range仅投递所需码点/脚本(可变轴也仅保留必要),缩小体积。避免主线程重活。 超长任务移到 Web Worker,避免阻塞交互。
设计
分层阴影。 至少两层:环境光 + 直射光。
边框清晰。 边框与阴影结合;半透明边框能增强边缘清晰度。
圆角套圆角。 子元素圆角 ≤ 父元素,且保持同心,曲线对齐。
色调一致。 在非中性背景上,让边框/阴影/文字向同一色调轻微偏移。
可达的图表。 使用色盲友好的配色。
最低对比。 比起 WCAG 2,更推荐 APCA 的感知对比评估。
交互增强对比。
:hover、:active、:focus的对比应高于静止态。浏览器 UI 与背景一致。 用
<meta name="theme-color" content="#000000">让浏览器主题色贴合页面背景。设置合适的配色方案。 深色主题下在
<html>标注color-scheme: dark,让滚动条等系统 UI 对比合适。文本抗锯齿与变换。 文本缩放会影响平滑;优先给外层容器做动画而非文本节点。如有残影可用
translateZ(0)或will-change: transform升层。避免渐变色带。 某些颜色/显示器会出现色带;可用纹理或噪声遮罩改善。
针对Vercel
这些偏好反映了 Vercel 的品牌与产品取向,并非通用指南。
文案写作
- 用主动语态。
不要说“CLI 将被安装”,而说“安装 CLI”。
标题与按钮用标题大小写(芝加哥风格)。 营销页使用句子式大小写。
清晰、简洁。 用最少的词表达清楚。
尽量用 & 而不是 and。
面向行动的语言。
不要说“你需要 CLI…”,而说“安装 CLI…”。
名词一致。 尽量减少独特术语的引入。
使用第二人称。 避免第一人称。
占位符一致。
字符串用:YOURAPITOKEN_HERE;数字用:0123456789。
- 计数用阿拉伯数字。
不要写“八个部署”,而写“8 个部署”。
货币格式一致。 在同一上下文中要么都 0 位小数,要么都 2 位,不要混用。
数字与单位间留空格。
不要写 10MB,应写 10 MB(推荐不换行空格:10 MB)。
- 默认使用积极语气。 即便是错误,也以鼓励、可解决的口吻描述。
不要说“你的部署失败了”,而说“出了点问题——请重试或联系支持”。
- 错误要指向出路。 不只说错了什么,还要告诉如何修复。
不要说“无效的 API 密钥”,而说“你的 API 密钥不正确或已过期。请在账户设置中生成新密钥。”文案与按钮/链接要帮助用户采取明确行动。
- 避免歧义。 标签清晰具体。
不要用“继续”,而用“保存 API 密钥”。
与代理集成
AGENTS.md 文件为代理提供指导。将此 AGENTS.md 与你的代理一起使用,以确保你的界面遵循这些指南。我们建议审核所有生成的界面。