mcpField
I
interface-kit

interface-kit

github.com/juliusbrussee设计与 UI1692.2k 次安装12 周前更新
代码仓库

关于 interface-kit

interface-kit 是用于设计和实现界面的指南,为没有 DESIGN.md 的项目提供默认规范。内容涵盖无障碍、性能、排版、布局、配色与动效,并规定已有设计规范优先。

主要功能

  1. 01优先考虑无障碍与性能
  2. 02提供排版和空间布局指导
  3. 03使用语义化颜色令牌与深色模式
  4. 04按交互频率制定动效建议
  5. 05DESIGN.md 优先于默认规范

适用场景

  1. 01为没有设计系统的项目构建界面
  2. 02检查无障碍和交互细节
  3. 03统一排版、配色与间距

安装

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

$npx skills add https://github.com/juliusbrussee/skills --skill interface-kit

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
accessibility-checklist.md
animation-playbook.md
component-patterns.md
review-checklist.md

详细介绍

Interface Kit:打造卓越界面的实现指南

如果项目根目录中存在 DESIGN.md,其设计令牌和规范将覆盖本技能中的所有默认设置。当项目没有设计系统时,本技能会提供合理的默认设置,以及无论是否存在设计系统都适用的实现指导。

如需深入了解任何章节,请参阅本技能 references/ 目录中的参考文件。


1. 核心理念

品味可以培养,并非与生俱来。研究优秀的界面为何让人感觉恰到好处。拆解你欣赏的应用——间距、节奏、阴影的分量。从“还不错”到“卓越”的差距,源自数百个细微决策;用户能感受到这些决策,却从不会有意识地察觉。

看不见的细节会层层累积。 一个圆角、一段缓动过渡、一道恰到好处的阴影——单独来看都无关紧要。但它们组合起来,便会成为“千百个几乎听不见的声音,和谐地一同歌唱”。这种累积效应,正是匠心与产出的区别。

美感就是优势。 精致并非虚荣。恰当的默认设置、经过考量的排版和有意设计的动效,都是实实在在的差异化优势。用户会信任那些让人感到用心的界面。投资者也会注意到。竞争对手无法轻易复制品味。

注重意图,而非强度。 大胆的极繁主义和精致的极简主义都行得通;真正行不通的是缺乏鲜明的主张。每个视觉决策都应源自明确的概念方向。如果你无法说明为何做出某项选择,就应重新考虑。

选定一个方向,并精准执行。 不要在不同风格之间犹豫不决。一张彻底贯彻粗野主义风格的页面,永远胜过一张“什么都有一点”的页面。坚定方向,然后不断打磨。

绝不要做出千篇一律的“AI 垃圾美学”。 不要在白色背景上无端添加渐变。不要用素材插画拼凑千篇一律的 Hero 区域。不要采用平庸、容易被遗忘、看起来属于任何产品的安全布局。每个界面都应有鲜明主张,让人一眼就能认出。


2. 优先级层级

实现 UI 时,按以下优先级依次处理。较高优先级的事项不可妥协;较低优先级的打磨则能进一步提升整体质量。

优先级级别含义
无障碍性CRITICAL对比度达到 4.5:1、支持键盘导航、采用 ARIA 语义、焦点环清晰可见。绝不交付排斥用户的内容。
性能HIGH使用 WebP/AVIF 图片、对首屏以下内容延迟加载、CLS < 0.1、仅在合成器线程上运行动画变换。
排版HIGH字体平滑、使用 text-wrap balance/pretty、数据采用 tabular-nums、行长最多 65ch。
布局与空间HIGH采用 4/8px 网格、使用同心圆角、优先考虑视觉对齐而非几何对齐。
颜色与主题MEDIUM使用 HSL 自定义属性和语义化令牌,分别测试深色模式的颜色配对。
动效与交互MEDIUM根据出现频率决定动画策略、动画时长为 150-300ms、默认使用 ease-out。
精致度与细节LOW采用多层阴影而非边框、为按钮添加按压反馈、使用错开进入动画。

绝不要为了追求 LOW 项而跳过 CRITICAL/HIGH 项。无法通过键盘导航的按钮,即使动画再精美,整体效果仍然是负面的。


3. 美学方向

在写下第一行 CSS 之前,先坚定选择一个大胆的美学方向。AI 生成的 UI 最常见的问题,就是趋同于同一种安全、平庸、容易被遗忘的风格。

选择一种风格

选择一种,并贯彻到底:

  • 极简主义 — 留白充足、等宽字体、强烈对比、几乎不加装饰
  • 极繁主义混乱风 — 层叠纹理、冲突的字体大小、信息密集、有意营造视觉噪声
  • 复古未来主义 — CRT 发光效果、等宽字体终端、扫描线、暗色背景上的霓虹色
  • 自然有机风 — 大地色调、圆润造型、纸张纹理、手绘点缀
  • 奢华精致风 — 衬线标题、柔和配色、充足留白、细腻的金色或奶油色点缀
  • 编辑/杂志风 — 戏剧化的字体层级、铺满版面的图像、打破网格的布局
  • 活泼大胆风 — 明亮的原色、粗壮的边框、夸张的阴影、轻快的动效
让复杂度匹配设计愿景

极繁主义设计需要精心编写代码——层叠背景、复杂网格结构、多套字体。极简主义设计则要求精准打磨——当没有任何东西可以掩饰瑕疵时,每个像素的间距都更重要。

禁用清单(没有 DESIGN.md 时)

在没有现成设计系统的情况下构建时,请避免使用这些过度泛滥、一看就像“AI 生成”的默认方案:

  • 字体:Inter、Roboto、Arial、system-ui 作为展示字体,Space Grotesk
  • 颜色:白色背景上的紫蓝渐变
  • 模式:居中标题文字 + CTA + 素材插画的通用主视觉区块

在浅色和深色主题、不同字体搭配、不同美学方向之间灵活变换。不要让不同项目采用相同的选择。

视觉肌理

通过以下方式增添层次感:渐变网格、噪点/颗粒叠加(filter: url(#noise))、层叠透明效果、细腻的背景图案、双色调图像处理。

DESIGN.md 优先于本节的所有内容。 如果 DESIGN.md 指定使用 Inter,就使用 Inter。如果它指定使用紫色渐变,就使用紫色渐变。禁用清单仅适用于没有设计系统、需要从零开始做美学选择的情况。


4. 排版基础

排版是影响设计效果最大的单一元素。做好了,平庸的布局也会让人感觉舒服;做不好,其他任何设计都无法补救。

根布局设置
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

在根布局应用字体平滑。在 macOS 上,默认的子像素渲染会让文字看起来比设计师预期的更粗。

文本换行
h1, h2, h3, h4, h5, h6 {
  text-wrap: balance;
}

p, li, dd, blockquote {
  text-wrap: pretty;
}

balance 会均匀分配标题的各行文字。pretty 会避免正文中出现落单的词。

数字显示
.data-value, .price, .counter, [data-numeric] {
  font-variant-numeric: tabular-nums;
}

对于任何动态更新的数字——价格、计数器、表格列——都使用 tabular-nums。否则,随着数字宽度变化,布局会发生偏移。

比例与节奏
  • 基础字号:正文至少为 16px。任何可读内容都不要小于 14px。
  • 行高:正文为 1.5-1.75,大标题为 1.1-1.3。
  • 最大行长:正文使用 max-width: 65ch。行过长会影响可读性。
  • 字体比例:选择一套一致的比例并坚持使用:12 / 14 / 16 / 18 / 24 / 32 / 48 / 64。
字体搭配

将独特的展示字体与精致的正文字体搭配使用。展示字体彰显个性,正文字体保证可读性。在同一字体家族中使用 font-weight 建立层级:

  • 标题:600-700(半粗体到粗体)
  • 正文:400(常规)
  • 标签/UI:500(中等)

始终提供字体栈回退选项:

--font-display: "Instrument Serif", "Georgia", serif;
--font-body: "Söhne", "Helvetica Neue", sans-serif;
--font-mono: "JetBrains Mono", "Fira Code", monospace;

5. 颜色与主题

HSL 自定义属性(shadcn 模式)
:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 222.2 47.4% 11.2%;
  --primary-foreground: 210 40% 98%;
  --secondary: 210 40% 96.1%;
  --secondary-foreground: 222.2 47.4% 11.2%;
  --muted: 210 40% 96.1%;
  --muted-foreground: 215.4 16.3% 46.9%;
  --accent: 210 40% 96.1%;
  --accent-foreground: 222.2 47.4% 11.2%;
  --destructive: 0 84.2% 60.2%;
  --destructive-foreground: 210 40% 98%;
  --border: 214.3 31.8% 91.4%;
  --ring: 222.2 84% 4.9%;
  --radius: 0.5rem;
}

定义语义令牌:primary、secondary、destructive、muted、accent、background、foreground。通过语义名称引用颜色——不要在组件中硬编码十六进制颜色值。

深色模式
.dark {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  /* ... desaturated, lighter tonal variants — NOT simply inverted */
}

深色模式并非“反转颜色”。应使用降低饱和度、色调更浅的变体。背景应采用深色,但不要纯黑(#000);文字应采用浅色,但不要纯白(#fff)。请单独测试深色模式下的对比度——在浅色模式下达标的颜色,在深色模式下可能不达标。

对比度要求
  • WCAG AA 最低标准:普通文本为 4.5:1,大号文本(18px+ 粗体或 24px+ 常规字重)为 3:1
  • 切勿仅通过颜色传达信息 — 始终搭配图标、标签或图案
  • 使用浏览器开发者工具中的对比度检查器或 axe-core 进行测试
色彩信心

鲜明的主色搭配醒目的点缀色,效果胜过犹豫不决、均匀分布的配色。选定一到两种主色,让调色板中的其他颜色退居次要位置。自信的配色层次分明;犹豫不决的配色将颜色均匀铺开,显得平淡。


6. 空间设计

同心圆角

这是最常见的导致嵌套 UI 元素看起来“不对劲”的问题:

outer_radius = inner_radius + padding
/* Correct: concentric */
.card        { border-radius: 16px; padding: 8px; }
.card-inner  { border-radius: 8px; }  /* 16 - 8 = 8 */

/* Wrong: same radius on parent and child */
.card        { border-radius: 12px; }
.card-inner  { border-radius: 12px; }  /* Looks bloated */

当几何居中看起来不协调时,改为进行视觉对齐。播放/暂停图标、下拉箭头和不对称字形通常需要手动微调 1-2px,才能看起来居中。

用阴影替代边框

使用多层透明的 box-shadow 值营造自然的纵深感,而不是使用边框:

.elevated {
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.04),
    0 2px 4px rgba(0, 0, 0, 0.04),
    0 4px 8px rgba(0, 0, 0, 0.04);
}

不同扩散范围的多层阴影能模拟光线的效果。单一的硬阴影看起来很不自然。

图像轮廓

为图像和媒体添加细微的内描边,使其在不同背景下都能保持一致的纵深感:

img, video {
  outline: 1px solid rgba(0, 0, 0, 0.06);
  outline-offset: -1px;
}
间距刻度

使用 4px / 8px 为基数的递增系统。每个间距值都应为 4 的倍数:

4 / 8 / 12 / 16 / 24 / 32 / 48 / 64 / 96 / 128

点击区域

所有交互元素的最小尺寸为 44x44px。如果视觉元素更小,可使用伪元素扩展点击区域:

.small-button::before {
  content: "";
  position: absolute;
  inset: -8px;
}
Z-Index 刻度

定义分层刻度,切勿使用随意指定的值:

--z-base: 0;
--z-dropdown: 10;
--z-sticky: 20;
--z-overlay: 40;
--z-modal: 100;
--z-toast: 1000;

7. 动效与交互

基于使用频率的决策框架

这是做出动画决策时最重要的思维模型:

频率示例动画
每天 100 次以上键盘快捷键、命令面板操作、切换标签页无。 不添加任何动画。立即响应。
每天几十次悬停效果、列表项导航、切换开关移除或大幅缩短。 最长 50-100ms。
偶尔模态框、抽屉、提示消息、页面过渡标准动画。 150-300ms。
很少 / 首次使用引导流程、庆祝效果、空状态可增添惊喜感。 300-500ms,可更复杂。

高频动画会让交互显得迟缓。低频交互若没有动效,则会显得突兀。应根据使用频率分配动画时长。

自定义缓动曲线

内置 CSS 缓动(ease、ease-in-out)效果太弱。请定义自定义曲线:

:root {
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}
时长指南
元素时长
按钮、切换开关100-160ms
工具提示125-200ms
下拉菜单、弹出框150-250ms
模态框、抽屉200-500ms
页面过渡250-400ms

UI 动画应控制在 300ms 以内。切勿在 UI 动画中使用 ease-in — 它会让动画前段停顿过久,显得迟缓。

进入与退出的不对称性

退出动画应比进入动画更柔和、更快。进入动画若为 250ms,退出动画应为 150-200ms。

拆分进入动画并错开播放

多个元素进入视口时,应按语义分组错开播放,间隔约 50-100ms:

.stagger-item {
  animation: fadeSlideIn 300ms var(--ease-out) both;
}
.stagger-item:nth-child(1) { animation-delay: 0ms; }
.stagger-item:nth-child(2) { animation-delay: 60ms; }
.stagger-item:nth-child(3) { animation-delay: 120ms; }
缩放动画

切勿从 scale(0) 开始动画。应从 scale(0.9) 或更高的值开始,并结合不透明度变化:

@keyframes scaleIn {
  from { opacity: 0; transform: scale(0.95); }
  to   { opacity: 1; transform: scale(1); }
}
按压反馈

所有可按压元素在 :active 状态下都应稍微缩小:

button:active {
  transform: scale(0.97);
}
可中断性

交互状态变化应使用 CSS 过渡(而非关键帧动画)。过渡可以在进行中被打断;关键帧动画则不能。这对于悬停状态、切换开关,以及任何用户可能快速交互的元素都很重要。

弹出框的变换原点

弹出框的变换原点应与触发元素相关联 — 它们应从触发元素处展开,而不是从中心展开。例外:模态框始终从中心展开。

工具提示悬停延迟

后续悬停时跳过工具提示延迟。如果用户已经等待过一个工具提示,则立即显示下一个。

减少动态效果
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

尊重 prefers-reduced-motion。减少动画,但不要完全取消不透明度和颜色过渡,因为它们能提供重要的反馈。

悬停门控

通过媒体查询控制悬停动画,避免触屏设备触发悬停状态后无法恢复:

@media (hover: hover) and (pointer: fine) {
  .card:hover { transform: translateY(-2px); }
}

参考 references/animation-playbook.md,深入了解弹簧物理、手势驱动动画和复杂编排。


8. 组件打磨

基础组件

使用 Radix UI 基础组件,构建易于访问且不带样式的基础。使用 CVA (class-variance-authority) 实现类型安全的组件变体:

import { cva } from "class-variance-authority";

const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline: "border border-input hover:bg-accent hover:text-accent-foreground",
        ghost: "hover:bg-accent hover:text-accent-foreground",
      },
      size: {
        sm: "h-9 px-3 text-sm",
        default: "h-10 px-4 py-2",
        lg: "h-11 px-8 text-lg",
      },
    },
    defaultVariants: { variant: "default", size: "default" },
  }
);
按钮
  • 按下时缩小(在 :active 上设置 transform: scale(0.97))
  • 显示可见的焦点环(绝不要在没有替代方案的情况下设置 outline: none)
  • 加载状态下用旋转指示器替换标签,同时保持按钮尺寸不变
  • 禁用状态设置为 opacity: 0.5 和 pointer-events: none
卡片
  • 卡片与内部元素的圆角保持同心
  • 使用分层阴影(而非边框)营造层次感
  • 悬停状态:轻微提升(translateY(-1px))并增强阴影
对话框 / 模态框
  • 限制焦点(键盘焦点无法移至后方元素)
  • 按 ESC 关闭,点击遮罩层外部关闭
  • 使用 transform-origin: center,进入动画采用淡入 + 缩放
  • 设置 aria-modal="true"、role="dialog"、aria-labelledby
表单
  • 始终显示标签,绝不要只使用占位符输入框
  • 在字段附近显示错误消息,并使用 aria-live="polite" 向屏幕阅读器提供提示
  • 渐进式披露:仅在需要时显示高级字段
  • 使用 React Hook Form + Zod 进行验证
主题

所有组件颜色均使用 shadcn CSS 变量模式(HSL 格式)。将客户端交互组件封装在服务端组件中,以兼容 Next.js App Router。

参考 references/component-patterns.md,查看包含可复制粘贴实现的完整组件目录。


9. 无障碍基础

优先使用语义化 HTML

优先使用 <button>、<nav>、<main>、<header>、<footer>、<article>、<section>,再考虑使用 ARIA。<button> 自带键盘处理、焦点管理和屏幕阅读器语义。<div onClick> 则没有这些功能。

键盘导航
  • Tab / Shift+Tab:在可聚焦元素间移动
  • Enter / Space:激活按钮和链接
  • 方向键:在列表、菜单、标签页、单选组内导航
  • Escape:关闭模态框、弹出层、下拉菜单
  • Home / End:跳转至列表中的首项 / 末项
焦点管理
  • 所有交互元素都要有可见的焦点环——绝不要在没有替代方案的情况下使用 outline: none
  • 在模态框内限制焦点(Tab 焦点在模态框内循环,而不是移至其后方)
  • 模态框 / 弹出层关闭时,将焦点还原至触发元素
  • 使用 focus-visible,仅为键盘用户显示焦点环,而不响应鼠标点击:
:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}
ARIA 属性
  • 图标按钮使用 aria-label:<button aria-label="Close menu">X</button>
  • 使用 aria-labelledby 将标题与区块关联
  • 使用 aria-describedby 将帮助文本或错误消息关联至输入框
  • 动态内容更新(提示消息、表单错误)使用 aria-live="polite"
  • 装饰性元素(文本标签旁的图标)使用 aria-hidden="true"
  • 可切换元素(下拉菜单、手风琴)使用 aria-expanded
颜色与对比度
  • WCAG AA:普通文本对比度为 4.5:1,大号文本为 3:1
  • 绝不要只用颜色作为唯一提示——应搭配图标、文本或图案
  • 在浅色和深色模式下都进行测试
图像与媒体
  • 有意义的图像使用描述性 alt 文本:alt="Dashboard showing 23% revenue growth"
  • 纯装饰性图像使用空 alt=""
  • 为视频添加字幕,为音频提供文字稿
导航辅助
  • 跳过链接:第一个可聚焦元素,在获得焦点前隐藏:
<a href="#main-content" class="sr-only focus:not-sr-only">
  Skip to main content
</a>
  • 标题层级:按顺序使用 h1 至 h6,不跳级。每页仅使用一个 <h1>。
触控目标
  • 交互区域至少为 44x44px
  • 相邻触控目标之间至少间隔 8px
  • 为较小的可视元素添加不可见内边距或伪元素,以扩大触控区域
测试
  • 自动化:在 CI 中运行 axe-core,Lighthouse 无障碍评分达到 90+
  • 手动:完整测试仅使用键盘进行导航
  • 屏幕阅读器:使用 VoiceOver(macOS)或 NVDA(Windows)进行测试
  • 视觉:将缩放比例调至 200%,检查是否有元素错位或重叠

完整的审查指南及通过/失败标准,请参阅 references/accessibility-checklist.md。


10. 交付前审查

在确认任何 UI 实现已完成之前,请逐项检查以下清单:

排版
  • 已应用字体平滑(-webkit-font-smoothing: antialiased)
  • 标题使用 text-wrap: balance
  • 动态数字使用 font-variant-numeric: tabular-nums
颜色
  • 所有颜色均通过语义化令牌引用,组件中没有硬编码的十六进制颜色值
  • 颜色对比度符合 WCAG AA(普通文本为 4.5:1,大号文本为 3:1)
  • 已单独测试深色模式下的对比度
空间
  • 嵌套圆角元素使用同心圆角
  • 间距始终遵循 4px/8px 比例
  • 交互元素的最小点击区域为 44x44px
  • 适合时使用阴影代替边框
动效
  • 动画频率与使用频率相匹配(高频操作不添加动画)
  • 不使用 transition: all,仅指定具体属性
  • 多个元素出现时,入场动画分开并错开播放
  • 遵循 prefers-reduced-motion 设置
无障碍
  • 所有交互元素均可通过键盘访问
  • 键盘导航时焦点环清晰可见(除非有替代方案,否则绝不使用 outline: none)
  • 优先使用语义化 HTML,再使用 ARIA
  • 动态内容更新时使用 aria-live

扩展版 30 项清单(含严重性评级和自动化测试命令),请参阅 references/review-checklist.md。

评论

支持 Markdown