mcpField
U
ui-design

ui-design

github.com/ckorhonen设计与 UI2470 次安装5 周前更新
代码仓库

关于 ui-design

面向 Agent 的前端界面设计规范 Skill,适用于使用 Tailwind CSS 构建或审查界面的开发者。它以明确约束覆盖无障碍、交互状态、动画、排版和布局。

主要功能

  1. 01规定 Tailwind CSS 默认值优先
  2. 02提供交互与无障碍要求
  3. 03约束动画属性与时长
  4. 04涵盖排版和布局规则
  5. 05检查加载、错误及空状态

适用场景

  1. 01构建 Tailwind CSS 界面组件
  2. 02审查前端无障碍与键盘交互
  3. 03设计动画、加载和错误状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ckorhonen/claude-skills --skill ui-design

安装后在 Claude Code 中输入/ui-design确认已加载。

详细介绍

UI 设计

为使用 Agent 构建更出色的界面制定明确约束。

适用场景

  • 使用 Tailwind CSS 构建 UI 组件
  • 实现动画或过渡效果
  • 添加带有键盘/焦点行为的交互元素
  • 审查前端代码的无障碍性
  • 设计具有适当 z-index 和间距的布局
  • 处理加载状态、错误处理或空状态

技术栈

要求规则
Tailwind CSS必须优先使用默认值(间距、圆角、阴影),再使用自定义值
动画库必须使用 motion/react(原名 framer-motion)实现 JS 动画
CSS 动画应使用 tw-animate-css 实现进入动画和微动画
类名逻辑必须使用 cn 工具(clsx + tailwind-merge)

组件

要求规则
交互式基础组件必须使用无障碍基础组件(Base UI、React Aria、Radix)处理键盘/焦点行为
现有组件必须优先使用项目现有的基础组件
一致性绝不能在同一个交互区域内混用不同的基础组件系统
新基础组件如果与技术栈兼容,应优先选择 Base UI
图标按钮仅含图标的按钮必须添加 aria-label
自定义行为除非明确要求,否则绝不能手动重建键盘或焦点行为

交互

要求规则
破坏性操作破坏性或不可逆操作必须使用 AlertDialog
加载状态应使用结构化骨架屏
视口高度绝不能使用 h-screen,应使用 h-dvh
固定元素必须遵循 safe-area-inset
错误显示必须在操作发生位置附近显示错误
输入行为绝不能阻止在 input 或 textarea 元素中粘贴

动画

要求规则
默认除非明确要求,否则绝不能添加动画
合成器属性只能对 transform、opacity 添加动画
布局属性绝不能对 width、height、top、left、margin、padding 添加动画
绘制属性应避免对 background、color 添加动画,小范围局部 UI(文本、图标)除外
进入缓动进入动画应使用 ease-out
反馈时长交互反馈绝不能超过 200ms
循环动画循环动画移出视口时必须暂停
无障碍性必须遵循 prefers-reduced-motion
自定义缓动除非明确要求,否则绝不能引入自定义缓动曲线
大型界面应避免对大图或全屏界面添加动画

排版

要求规则
标题必须使用 text-balance
正文文本段落必须使用 text-pretty
数据必须使用 tabular-nums
密集型 UI应使用 truncate 或 line-clamp
字间距除非明确要求,否则绝不能修改 letter-spacing(tracking-)

布局

要求规则
Z-index必须使用固定刻度(不能使用任意 z-x)
正方形元素应使用 size-x,而不是 w-x + h-x

性能

要求规则
模糊效果绝不能对大范围 blur() 或 backdrop-filter 界面添加动画
Will-change绝不能在动画进行期间以外应用 will-change
useEffect绝不能用于可通过渲染逻辑实现的内容

设计

要求规则
渐变除非明确要求,否则绝不能使用
紫色/多色渐变绝不能使用
发光效果绝不能将其用作主要提示
阴影除非明确要求,否则应使用 Tailwind CSS 默认刻度
空状态必须提供一个明确的下一步操作
强调色每个视图应限制使用一种
颜色令牌引入新令牌前,应优先使用现有主题或 Tailwind CSS 令牌

常见陷阱

最常见的 UI 设计问题出现在间距、颜色对比度、移动端适配、状态管理和视觉层次方面。这些问题是在 Agent 构建界面时反复犯错后总结出来的。

1. 间距不一致(边距随意,没有规范)

问题: 混用各种 Tailwind 间距值,且没有明确的规范,会让布局显得杂乱无章。

// ❌ WRONG - arbitrary pixel values, no spacing system
<div className="ml-[13px] mr-[22px] pt-[7px]">Content</div>

// ✅ CORRECT - use system scales
<div className="ml-4 mr-4 pt-4">Content</div>

为什么会失败:

  • 设计看起来像是随意拼凑的(有些间距是 2px,有些是 16px,毫无规律)
  • 移动端布局会出问题(间距无法按比例缩放)
  • 无法对齐(间隙无法与网格对齐)

解决方法:

  • 始终使用 Tailwind 间距比例(0、1、2、3、4、6、8、12、16、24、32 等)
  • 为常见模式定义间距规范:
    • 按钮内边距:px-4 py-2
    • 卡片内边距:p-6
    • 区块之间的间隙:gap-8
    • 嵌套间距:ml-6(而不是 ml-3)
  • 为相关元素分组,并保持间隙一致(所有水平列表使用相同的 gap-x)
2. 颜色对比度不足(违反无障碍要求)

问题: 颜色组合未达到 WCAG AA 对比度比例(文本为 4.5:1,UI 组件为 3:1),导致视力较弱的用户难以阅读内容。

// ❌ WRONG - gray-400 text on gray-100 background fails contrast
<p className="text-gray-400 bg-gray-100">Important content</p>

// ✅ CORRECT - gray-700 on gray-100 passes WCAG AA
<p className="text-gray-700 bg-gray-100">Important content</p>

为什么会失败:

  • 约 4-5% 的用户有色盲,而更广泛的群体中,超过 15% 的人存在某种视力障碍
  • 使用高亮度屏幕(如手机)的用户无法阅读对比度较低的文本
  • 存在法律责任风险(许多司法管辖区要求符合 WCAG 标准)

解决方法:

  • 使用对比度足够的颜色组合:
    • 在任何背景上使用 text-gray-900/text-white(始终安全)
    • 在浅色背景上使用 text-gray-700
    • 在深色背景上使用 text-gray-300
  • 测试颜色: 使用在线对比度检查工具(https://webaim.org/resources/contrastchecker/)
  • 避免有问题的组合:
    • gray-400 配 gray-100 ❌
    • red-500 配 pink-100 ❌
    • 禁用状态:白色背景上使用 text-gray-400,彩色背景上使用 text-gray-600
  • 彩色文本(非灰色): 使用较深的色调(red-700,而非 red-300)
3. 不适合移动端的布局(触控目标过小、横向滚动)

问题: 触控目标小于 44×44px、需要横向滚动,或布局无法适配较窄的视口。

// ❌ WRONG - button too small, no responsive layout
<button className="px-2 py-1 text-xs">Click me</button>
<div className="flex gap-2">
  <div className="w-80">Sidebar</div>
  <div className="w-80">Content</div>
</div>

// ✅ CORRECT - hit target size, responsive stack
<button className="px-4 py-3 md:px-6 md:py-3">Click me</button>
<div className="flex flex-col md:flex-row gap-4">
  <div className="w-full md:w-80">Sidebar</div>
  <div className="flex-1">Content</div>
</div>

为什么会失败:

  • 40% 的流量来自移动端;按钮太小会难以点击
  • 在手机上横向滚动会严重影响用户体验
  • 在桌面端可用的布局,在移动端可能完全无法使用

解决方法:

  • 触控目标最小尺寸:44×44px
    • 按钮:至少使用 px-4 py-3(标准值:px-6 py-3)
    • 链接:将链接放入更大的可点击区域中
  • 在移动端改为纵向排列: 默认使用 flex-col,桌面端使用 md:flex-row
  • 使用响应式宽度:
    • 移动端使用 w-full,桌面端使用 md:w-80 或 md:w-1/3
    • 灵活布局中使用 flex-1,而非固定宽度
  • 测试响应式效果: 检查 375px(iPhone SE)和 768px(平板)的断点
  • 避免横向滚动: 绝不要让用户横向滚动
4. 状态缺失(加载、错误、空内容、禁用)

问题: 界面只显示顺利完成时的情况,在加载、出错或内容为空时会无声失败。

// ❌ WRONG - no feedback states
<button onClick={save}>Save</button>
<div>{data.map(item => <ItemCard item={item} />)}</div>

// ✅ CORRECT - all states accounted for
<button onClick={save} disabled={loading}>
  {loading ? 'Saving...' : 'Save'}
</button>

{loading && <LoadingSkeleton />}
{error && <ErrorAlert message={error} />}
{!loading && data.length === 0 && <EmptyState action="Create your first item" />}
{!loading && !error && data.map(item => <ItemCard item={item} />)}

为什么会失败:

  • 用户不知道操作是否成功(没有反馈就会让人觉得操作失败了)
  • 空列表看起来像是出了问题,而非有意为空
  • 出错后没有恢复途径

解决方法:

  • 加载状态: 使用结构化骨架屏(而非旋转加载图标)
    • 内容加载期间保持布局稳定
    • 让用户看到即将显示的内容,而不只是加载动画
  • 错误状态: 在失败的操作旁显示
    • 说明发生了什么以及如何解决
    • 提供重试按钮
  • 空状态: 明确呈现,并提供可执行操作
    • “还没有项目” → “创建你的第一个项目”(按钮)
    • 说明空状态的含义,以及如何添加内容
  • 禁用状态: 始终提供视觉反馈
    • disabled={true} + opacity-50 或 cursor-not-allowed
    • 绝不要在不说明原因的情况下直接禁用
5. 层级不清(所有内容看起来同等重要)

问题: 所有文本大小相同、颜色权重相同、间距相同——没有任何内容突出显示。

// ❌ WRONG - flat hierarchy
<div className="text-lg text-gray-700">
  <div className="text-lg text-gray-700">Subheading</div>
  <div className="text-lg text-gray-700">Subtitle</div>
  <button className="text-lg px-4 py-2">Action</button>
</div>

// ✅ CORRECT - clear hierarchy
<div>
  <h1 className="text-3xl font-bold text-gray-900">Title</h1>
  <h2 className="text-xl font-semibold text-gray-700 mt-6">Subheading</h2>
  <p className="text-base text-gray-600 mt-2">Subtitle</p>
  <button className="mt-6 px-6 py-3 bg-blue-600 text-white font-semibold rounded">
    Primary Action
  </button>
</div>

为什么会失败:

  • 用户不知道应该先看哪里
  • 浏览页面的速度更慢(缺乏便于快速浏览的结构)
  • 重要操作容易被忽略

修复方法:

  • 大小层级:
    • 标题:text-3xl (h1) → text-2xl (h2) → text-xl (h3)
    • 正文:text-base(段落)→ text-sm(次要内容)
  • 字重层级:
    • 主要操作:font-bold 或 font-semibold
    • 重要文本:font-semibold
    • 正文:font-normal
    • 次要内容:font-normal,并使用较浅的颜色
  • 颜色层级:
    • 主要文本:text-gray-900
    • 次要文本:text-gray-600
    • 第三级文本:text-gray-500
  • 间距层级:
    • 区块间距:gap-8(最大)
    • 组件间距:gap-4
    • 密集内容:gap-2
  • 每个视图使用一种强调色: CTA 使用单一颜色,不要使用多种颜色争夺注意力

快速参考

允许的动画属性
transform, opacity
禁止的动画属性
width, height, top, left, margin, padding, blur(), backdrop-filter
必需的无障碍模式
// Icon button - always add aria-label
<button aria-label="Close dialog">
  <XIcon />
</button>

// Respect reduced motion
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; }
}
类名实用工具模式
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

评论

支持 Markdown