原文: vercel.com/design/guid… ,下面是经过人工校验的译文
界面的成功源于数百个细微选择。这是一份动态且非详尽的决策清单。大多数指南与框架无关,部分针对 React/Next.js。欢迎提供反馈。
交互
- 键盘无处不在。 所有流程均可通过键盘操作,并遵循 WAI-ARIA 创作模式。
- 清晰的焦点。 每个可聚焦元素都显示可见的焦点环。优先使用
: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, viewport-fit=cover" />。 - 尊重缩放。 切勿禁用浏览器缩放。
- 水合安全的输入。 输入在水合后不得丢失焦点或值。
- 不要阻止粘贴。 切勿在
<input>或<textarea>中禁用粘贴。 - 加载按钮。 显示加载指示器并保留原始标签。
- 最短加载状态持续时间。 如果显示旋转图标/骨架屏,请添加短暂的显示延迟(约 150–300 毫秒)和最短可见时间(约 300–500 毫秒),以避免快速响应时的闪烁。
- URL 作为状态。 将状态持久化到 URL 中,以便分享、刷新、前进/后退导航正常工作,例如使用 nuqs。
- 乐观更新。 在成功可能性高时立即更新 UI;根据服务器响应进行协调。失败时,显示错误并回滚或提供撤销功能。
- 省略号表示进一步输入。 打开后续操作的菜单选项(例如“重命名…”)以省略号结尾。
- 确认破坏性操作。 要求确认或提供带有安全窗口的撤销功能。
- 防止控件上的双击缩放。 设置
touch-action: manipulation。 - 点击高亮符合设计。 设置
webkit-tap-highlight-color。 - 设计宽容的交互。 控件通过宽大的点击目标、清晰的视觉提示和可预测的交互来最小化挑剔性,即 预测锥。
- 工具提示时机。 延迟组内第一个工具提示;后续同级无延迟。
- 过度滚动行为。 有意设置
overscroll-behavior: contain,例如在模态框/抽屉中。 - 滚动位置持久化。 前进/后退恢复之前的滚动位置。
- 为速度自动聚焦。 在具有单个主要输入的桌面屏幕上自动聚焦。很少在移动设备上自动聚焦,因为键盘弹出会引发布局偏移。
- 无死区。 如果控件的一部分看起来可交互,那么它就应该可交互。不要让用户猜测在哪里进行交互。
- 深度链接一切。 筛选器、标签页、分页、展开面板,以及每次使用
useState时。 - 干净的拖拽交互。 在元素被拖拽时禁用文本选择并应用
inert(防止交互),以免同时发生选择/悬停。 - 链接就是链接。 使用
<a>或<Link>进行导航,以便标准浏览器行为生效(Cmd/Ctrl+点击、中键点击、右键在新标签页打开)。切勿用<button>或<div>替代导航链接。 - 宣布异步更新。 对提示和内联验证使用礼貌的 aria-live。
- 支持区域设置的键盘快捷键。 为非 QWERTY 布局国际化键盘快捷键。显示平台特定符号。
动画
- 尊重
prefers-reduced-motion。 提供减少动画的变体。 - 实现偏好。 优先使用 CSS,尽可能避免主线程 JS 驱动的动画。
- 偏好:CSS > Web Animations API > JavaScript 库,例如 motion。
- 合成器友好。 优先使用 GPU 加速属性(
transform,opacity),避免触发重排/重绘的属性(width,height,top,left)。 - 必要性检查。 仅在动画能阐明因果关系或增添刻意愉悦感时才使用,例如 北极光。
- 缓动符合主题。 根据变化内容(大小、距离、触发器)选择缓动效果。
- 可中断。 动画可通过用户输入取消。
- 输入驱动。 避免自动播放;响应操作进行动画。
- 正确的变换原点。 将运动锚定到其“物理”起始位置。
- 切勿
transition: all。 明确列出仅打算动画的属性(通常是opacity,transform)。all可能无意中动画影响布局的属性,导致卡顿。 - 跨浏览器 SVG 变换。 将 CSS 变换/动画应用于
<g>包装器,并设置transform-box: fill-box; transform-origin: center;。Safari 历史上在 SVG 上存在 transform-origin 的 bug,分组可避免原点计算错误。
布局
- 视觉对齐。 当感知优于几何时,调整 ±1px。
- 刻意对齐。 每个元素都故意与某物对齐,无论是网格、基线、边缘还是视觉中心。无意外定位。
- 平衡组合中的对比度。 当文本和图标并排时,调整粗细、大小、间距或颜色,以免冲突。例如,细线图标在中等粗细文本旁可能需要加粗线条。
- 响应式覆盖。 在移动设备、笔记本电脑和超宽屏上验证。对于超宽屏,缩放至 50% 以模拟。
- 尊重安全区域。 使用安全区域变量考虑刘海屏和内边距。
- 无过度滚动条。 仅渲染有用的滚动条;修复溢出问题以防止不必要的滚动条。
- 让浏览器处理尺寸。 优先使用 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>和“跳至内容”链接。 - 从 Logo 获取品牌资源。 右键点击导航栏 Logo 以快速访问品牌资源。
- 粘连术语使用不换行空格。 使用不换行空格
使单位、快捷键和名称保持在一起:10 MB→10 MB,⌘ + K→⌘ + K,Vercel SDK→Vercel SDK。无空格时使用⁠。
表单
- 回车提交。 当文本输入框获得焦点时,回车键提交。
- 文本区域行为。 在
<textarea>中,⌘/⌃+回车提交;回车插入新行。 - 处处有标签。 每个控件都有
<label>或与标签关联,以便辅助技术使用。 - 标签激活。 点击
<label>聚焦关联控件。 - 提交规则。 在提交开始前保持提交按钮启用;然后在请求进行中禁用,显示旋转图标,并包含幂等性密钥。
- 不要阻止输入。 即使字段仅接受数字,也允许任何输入并显示验证反馈。完全阻止按键会令人困惑,因为用户得不到解释。
- 不要预先禁用提交。 允许提交不完整表单以显示验证反馈。
- 控件上无死区。 复选框和单选按钮避免死区;标签和控件共享一个宽大的点击目标。
- 错误位置。 在字段旁显示错误;提交时聚焦第一个错误。
- 自动完成与名称。 设置
autocomplete和有意义的name值以启用自动填充。 - 选择性拼写检查。 为电子邮件、代码、用户名等禁用拼写检查。
- 正确的类型与输入模式。 为更好的键盘和验证使用正确的
type和inputmode。 - 占位符表示空状态。 以省略号结尾。
- 占位符值。 将占位符设置为示例值或模式,例如
+1 (123) 456-7890和sk-012345679…。 - 未保存的更改。 在可能丢失数据的导航前发出警告。
- 密码管理器与 2FA。 确保兼容性并允许粘贴一次性代码。
- 不要为非认证字段触发密码管理器。 对于“搜索”等输入,避免使用保留名称(例如 password),使用
autocomplete="off"或特定令牌如autocomplete="one-time-code"用于 OTP 字段。 - 文本替换与扩展。 有些会添加尾随空格。输入应修剪值以避免显示令人困惑的错误消息。
- Windows
<select>背景。 在原生<select>上显式设置background-color和color,以避免 Windows 暗模式对比度错误。
性能
- 设备/浏览器矩阵。 测试 iOS 低功耗模式和 macOS Safari。
- 可靠测量。 禁用增加开销或改变运行时行为的扩展。
- 跟踪重新渲染。 最小化并加速重新渲染。使用 React DevTools 或 React Scan。
- 分析时限制。 使用 CPU 和网络限制进行测试。
- 最小化布局工作。 批量读/写;避免不必要的重排/重绘。
- 网络延迟预算。
POST/PATCH/DELETE在 <500ms 内完成。 - 按键成本。 优先使用非受控输入;使受控循环成本低廉。
- 大型列表。 虚拟化大型列表,例如 virtua。
- 明智预加载。 仅预加载首屏图像;其余懒加载。
- 无图像引起的 CLS。 设置显式图像尺寸并预留空间。
- 预连接到源。 对资产/CDN 域使用
<link rel="preconnect">(需要时使用 crossorigin)以减少 DNS/TLS 延迟。 - 预加载字体。 为关键文本避免闪烁和布局偏移。
- 子集化字体。 通过 unicode-range 仅发送使用的代码点/脚本(将可变轴限制为所需内容)以缩小尺寸。
设计
- 分层阴影。 通过至少两层模仿环境光和直射光。
- 清晰的边框。 结合边框和阴影;半透明边框改善边缘清晰度。
- 嵌套圆角。 子圆角 ≤ 父圆角且同心,使曲线对齐。
- 色调一致性。 在非中性背景上,将边框/阴影/文本色调调整为相同色调。
- 可访问的图表。 使用色盲友好调色板。
- 最小对比度。 优先使用 APCA 而非 WCAG 2 以获得更准确的感知对比度。
- 交互增加对比度。
:hover,:active,:focus比静止状态具有更高对比度。 - 浏览器 UI 匹配您的背景。 设置
<meta name="theme-color" content="#000000">以 使浏览器主题颜色与页面背景对齐。 - 文本抗锯齿与变换。 缩放文本会改变平滑度。优先动画包装器而非文本节点。如果伪影持续存在,设置
translateZ(0)或will-change: transform以提升到其独立图层。 - 避免渐变条带。 某些颜色和显示类型会出现颜色条带。可改用遮罩。
Vercel 专属
这些偏好反映了 Vercel 的品牌和产品选择。它们并非通用指南。
文案撰写
- 主动语态。
- 与其说“CLI 将被安装”,不如说“安装 CLI。”
- 标题与按钮使用标题大小写 (芝加哥)。在营销页面上,使用句子大小写。
- 清晰简洁。 尽可能使用最少的字词。
- 优先使用
&而非and。 - 面向行动的语言。
- 与其说“您将需要 CLI…”,不如说“安装 CLI…”。
- 保持名词一致。 尽可能引入最少的独特术语。
- 使用第二人称写作。 避免第一人称。
- 使用一致的占位符。
- 字符串:
YOUR_API_TOKEN_HERE。数字:0123456789。
- 字符串:
- 计数使用数字。
- 与其说“八次部署”,不如说“8 次部署”。
- 一致的货币格式。 在任何给定上下文中,货币显示为 0 或 2 位小数,切勿混合两者。
- 数字与单位用空格分隔。
- 与其说
10MB,不如说10 MB。 - 使用不换行空格,例如
10 MB。
- 与其说
- 默认使用积极语言。 即使是错误,也以鼓励、解决问题的方式构建消息。
- 与其说“您的部署失败了”,不如说“出了点问题——请重试或联系支持。”
- 错误消息引导退出。 不仅说明哪里出错——还要告诉用户如何修复。
- 与其说“无效的 API 密钥”,不如说“您的 API 密钥不正确或已过期。请在账户设置中生成新密钥。” 文案和按钮/链接应提供指导并给出明确操作。
- 避免歧义。 标签清晰具体。
- 与其使用按钮标签“继续”,不如说“保存 API 密钥”。
与代理集成
AGENTS.md 文件为代理提供指导。将此 AGENTS.md 与您的代理一起使用,以确保您的界面遵循这些指南。我们建议审核所有生成的界面。