关于 design-system
design-system 是面向前端开发者的实现技能,适用于构建组件、页面和设计系统,规定了设计令牌、排版、加载行为、界面固定区域、动效与布局的做法。
主要功能
- 01语义化颜色令牌架构
- 02排版层级指导
- 03按优先级加载资源
- 04字体加载与布局稳定
- 05缓慢内容的平稳呈现
- 06动效与滚动叙事指导
适用场景
- 01实现一致的 UI 令牌系统
- 02减少加载过程中的布局偏移
- 03设计清晰易读的排版层级
- 04构建滚动驱动的编辑图形
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill design-system安装后在 Claude Code 中输入/design-system确认已加载。
附带文件references/motion-choreography.md
详细介绍
设计系统
适用场景
当你需要前端设计的机械式实现规范时,请使用此技能:令牌架构、字体排版层级、加载顺序、FOUT 防护、界面框架稳定性、动效时序、颜色语义。构建组件、页面或设计系统时,请结合 design 使用。审美方向与这些实现指南相互独立。
实现 UI(组件、页面或设计系统)时,请结合 design 使用。每项颜色、字体和动效选择都应遵循这些规则。
令牌架构
所有颜色都映射到一小组基础令牌。不要使用随意的十六进制值。
- 前景色:文本层级(主要、次要、弱化)。
- 背景色:表面层级(基础、凸起、叠加)。
- 边框:分隔层级(微妙、默认、强调)。
- 品牌色:品牌标识和主要强调色。
- 语义色:危险、警告、成功(以及可选的信息色)。
在代码中使用令牌(CSS 变量、主题对象);切勿为 UI 硬编码十六进制颜色。
字体排版
- 层级:标题——字重更粗、字间距更紧,以突出呈现。正文——字重舒适,便于阅读。标签/UI——字重适中,在较小字号下也清晰易读。数据——使用等宽字体,并使用
tabular-nums实现对齐。 - 结合字号、字重和字间距,让层级一目了然。如果眯起眼睛仍分不清标题和正文,说明层级不够明显。
- 字体:将展示字体与正文字体搭配使用,确保层级一目了然。具体选择哪些字体属于设计方向,而非实现规范——根据领域挑选,并跳出你的第一直觉/默认选择(平均值);参见 design-spatial §2。
- 数据(仅用于功能性场景):真实且需对齐的数字、ID、时间戳应使用等宽字体并设置
tabular-nums——当数值按列对齐时,等宽字体才有用。不要为了营造「技术感」而在装饰性眉题/元数据微型文字(「35MM · DEVELOP · SCAN」、虚构的规格说明)中随意使用等宽字体——这只是当前流行的劣质设计风潮,不是真正的数据。参见 design-spatial §2。
加载顺序——先看到的,先加载
首屏必须快速呈现完整、正确的内容。根据用户看到内容的先后顺序安排每项资源的加载;其余内容稍后加载。
- 只优先加载首屏内容(主视觉文案、主视觉图片/视频、品牌标识)。预加载所有内容,效果等同于什么都不预加载——真正关键的内容会输掉带宽竞争。挑出首屏中少数几项内容,优先加载这些内容。
- 字体:自托管 WOFF2。 将 OTF/TTF 转换为 WOFF2(Brotli 压缩;字节数约减半,字形不变),并通过
<link rel="preload" as="font" type="font/woff2" crossorigin>预加载首屏中使用的字重。绝不要使用会阻塞渲染的第三方字体样式表——Google Fonts 的<link>会增加一次 CSS 往返请求,并在字体开始下载前额外进行 DNS/TLS 握手;应改用自托管字体。 - LCP 图片/视频: 为主视觉图片(或视频封面图)设置
fetchpriority="high";如果图片通过 CSS 引用,则使用<link rel="preload" as="image">预加载(解析器无法提前发现 CSSurl())。主视觉区域绝不能留空——提供封面图/低分辨率占位图,避免出现空白画面。 - 首屏以下内容: 为图片设置
loading="lazy" decoding="async";为视频设置preload="none"(或"metadata");对非关键 JS 使用defer。务必预留空间(使用aspect-ratio,或width+height),以免延迟加载的媒体导致布局偏移(CLS)。 - 保持会阻塞渲染的
<head>内容精简:内联关键 CSS,其余部分延后加载。
字体加载 — 内容易读,度量稳定
font-display: swap 就是弹出效果:先绘制回退字体,然后切换到 Web 字体并重新排版。不要将它用于用户会看到加载过程的文本(标题、字标、首屏文案)。兼顾视觉稳定性与即时可读性;不要在等待字体加载时隐藏重要标题或控件。
- 仅对于非必要的装饰性展示文本,可选择在真实字体加载完成前隐藏。 在
<head>中同步为<html>添加fonts-pending类,让展示字体文本保持opacity: 0。在document.fonts.ready时——对每个关键字体调用document.fonts.load('<weight> 1em "Family"')触发加载——切换为fonts-ready,并在约 0.5s 内淡入文本。务必设置约 2.5s 的安全超时,无论如何都显示文本,避免字体加载失败导致文本永久隐藏。 - 配合预加载和 WOFF2(见上文),将隐藏时间缩短至几百毫秒,而非几秒;淡入效果会显得自然,不像加载停滞。
- 对于允许出现难以察觉的字体切换的正文文本,至少要消除重新排版:定义一个经过
size-adjust/ascent-override/descent-override调整的回退@font-face(或font-family回退字体),使回退字体与 Web 字体的度量一致,这样切换时就不会产生偏移。
示例 — 一个 AR 产品调研页面:头部脚本切换 fonts-pending → fonts-ready(字体加载完成后标题淡入,超时后 2.5s 显示),预加载首屏所需的四种 WOFF2 字重,并自行托管品牌字体,避免请求 Google。
加载缓慢的内容——绝不显示难看的中间状态
任何可能需要明显时间才能就绪的内容——字体(上文所述)、大图、视频、<canvas> 场景、Three.js / WebGL、延迟加载的 React 岛,以及任何需要从网络获取内容或在主线程执行繁重初始化的内容——都必须快速呈现或平稳加载。浏览器的默认行为(空白框 → 局部绘制 → 重新布局 → 最终状态)就是难看的中间状态。要避免它。
有两种方法;两种都要用:
- 加快呈现速度。 压缩资源(字体用 WOFF2,glTF 用 Draco,图片用 WebP/AVIF,视频用 h264/h265 并设置
preload="metadata")。预加载首屏实际需要的少量资源(<link rel="preload">)。首屏以下的内容采用延迟加载,避免与 LCP 资源争抢。预留容器空间(aspect-ratio、width+height),以免延后加载的内容导致 CLS。 - 平稳加载。 在加载期间用有样式的占位内容遮住内容,随后淡入实际内容。骨架框、模糊的低分辨率海报图、单个 ASCII 字符,甚至只是容器的背景色——任何符合设计风格的内容,都比默认的局部绘制效果好。
以下是具体的“难看”表现及修复方法:
| 表现 | 修复方法 |
|---|---|
注释标签在 JS 为其设置位置之前都堆叠在 translate(0,0)(容器左上角)处 | 将标签初始设为 opacity: 0,并添加 transition: opacity ~0.35s;首次投影时设置行内 opacity 值 → CSS 将其淡入。 |
| Canvas/WebGL 首次渲染时有一帧显示为空白或黑屏 | 在同一个框内显示占位内容(CSS 绘图、低分辨率海报图或纸张/骨架填充);首帧实际内容渲染完成后将其移除。 |
| 延迟加载的图片突然出现,造成布局跳动 | 设置 aspect-ratio,并对首屏内容使用 <link rel="preload">,或对首屏以下内容使用 loading="lazy" decoding="async";首次绘制时,在 load 事件中将其从 opacity:0 淡入。 |
| 播放时,视频海报图突然切换到首帧 | 使用与你自行控制的静帧一致的 poster;触发 playing 事件时,干净的交接已经完成。 |
| 3D 模型毫无过渡地“出现”在屏幕中央 | 保持 canvas 可见,但将其设为 opacity: 0;在 GLTFLoader 成功回调中、首次 tick() 之后,切换 .viewer-ready 类(或设置行内 opacity)。 |
| 延迟加载的 React 岛闪现一个比没有 UI 还难看的回退界面 | 将 Suspense 回退内容替换为贴合最终布局的骨架屏,而不是加载指示器。 |
经验法则:如果用户能在加载过程中截下页面,而你会觉得难为情,那就应该提供平稳的加载状态。占位内容不必花哨——但必须经过设计、尺寸合适,并符合即将呈现内容的设计语言。
界面固定部分保持静止——状态文本绝不改变布局尺寸
固定界面元素(页眉、导航栏、工具栏、搜索栏、状态区域)无论显示什么文字,都必须保持恒定高度。临时状态 / 加载 / 说明文字——例如“正在加载模型……”“N 个匹配项 · 已索引 M 项”、空状态提示——不得换成两行并把相邻控件挤下去。状态区域随消息变化而增高或缩小,是布局抖动问题,而不是动态内容。
- 仅对可选状态摘要限制为单行: 使用
white-space: nowrap; overflow: hidden; text-overflow: ellipsis,让过长的消息截断,而不是换行。 - 预先留出空间: 为容器设置固定的
height(或min-height),尺寸足以容纳消息,确保最短、最长及空状态占据相同的空间。
界面固定部分保持不动时,只有内容区域应当移动;临时文本引起的布局偏移会让产品显得粗制滥造。(这能避免的具体问题:在搜索应用中,模型加载提示换成两行,把搜索栏往下挤。)
动效
- 保持节奏一致且有目的;一个精心编排的时刻(使用
animation-delay错开页面加载)胜过零散的微交互。HTML 优先使用纯 CSS;React 使用 Motion 库。(面向公众/多用户的项目应遵循prefers-reduced-motion。) - 克制/专业 UI 的默认值(仅作起点,并非硬性规定):微交互约 150ms,较大的过渡为 200–250ms,使用 ease-out。俏皮/玩具般的基调(设计思维)可能更适合弹簧/弹跳效果和更长的节拍——动效感受应契合所选方向,而非默认采用这些数值。
- 编排——对于单个微交互以外的任何内容(路由/页面过渡、列表重排、内容显现、共享元素),请加载 references/motion-choreography.md:何时过渡值得保留(必须传达某种信息,否则就删掉)、应实现哪些类型以及按什么顺序、按导航类型设定样式(仅在层级式/有序导航中使用方向性滑动——同级页面之间滑动会错误暗示深度;横向切换则使用淡入淡出)、时长表,以及制作要点(仅使用合成器属性、变形时使用动态模糊、切勿栅格缩放文本、隔离持久化界面元素)。与框架无关。
滚动驱动叙事(滚动叙事)
对于说明性/编辑类/数据讲解内容,优先使用滚动驱动图形,而非点击交互控件。读者通常会直接滚动;让他们寻找并点击开关来推进讲解会增加阻力,也容易被跳过。采用 NYT/Pudding 模式:固定一张图形(position: sticky),让简短的文字“步骤”从旁滚过,并由每个步骤驱动图形的状态。
- **实现机制:**使用一个
IntersectionObserver,并设置rootMargin: '-48% 0px -48% 0px'(threshold 为 0),这样步骤恰好在穿过视口中线时变为“激活”状态;激活索引会重新渲染固定的图形。约 30 行代码——这就是去掉依赖后的 scrollama;不要添加滚动库。 - **布局:**采用两列布局——一列滚动显示步骤,另一列显示
sticky top-0 h-screen的图形;移动端则改为上下排列,并将图形固定在顶部。每个步骤设置约 85vh 的高度,确保每次只有一个步骤居中;调暗未激活的步骤卡片(opacity:.3),让当前步骤更醒目。 - 图形是激活步骤的纯函数(
graphic(active)),自身不保存点击状态——因此截图/导出结果也具有确定性,并且可降级为静态图。对状态间的变化(颜色/宽度/不透明度)进行动画处理(300–700ms),让滚动体验连贯,而非跳跃。 - 何时不适用:仪表板、工具、表单——任何由用户操作而非阅读的内容——都应保持交互性。滚动叙事适用于讲述,由你掌控顺序。(面向公众/多用户的构建:遵循上文“动效”说明中的
prefers-reduced-motion;保留状态变化,但取消补间动画。)
空间构图与布局
网格系统、8 点间距尺度、视觉重量平衡、对齐方式,以及“渲染后再评议”的循环,详见 design-spatial (../design-spatial/SKILL.md)——它是本文件中设计令牌/字体/颜色部分的机械实现补充。每当构建页面、仪表板或组件时,都应加载它。(适用于此处的方向要点:构图的野心应与愿景相匹配——极繁主义适合精致/层叠的代码;极简/精致则要求克制和精准的间距。)
嵌套圆角(仅当一个圆角元素位于另一个圆角元素内时)
这并非是在鼓励使用圆角,而是规定一个圆角元素嵌套在另一个圆角元素中的情况(例如卡片中的按钮、容器中的内嵌面板)。嵌套时:
- 子元素的圆角半径 ≤ 父元素的圆角半径,绝不能更大(子元素的圆角比父元素更圆,会显得像是向外鼓起)。
- 同心是理想状态:
child_radius = max(0, parent_radius − gap)(它们之间的内边距),这样两条曲线便会平行延伸,内侧圆角也会呼应外侧圆角。在圆角父元素中使用平直或无圆角的子元素也没问题;看起来不协调的是不匹配、不同心的曲线。
颜色
- 从领域中汲取配色:颜色应当让人觉得源自产品所处的世界,而不是后来叠加上去的。
- 不止于冷暖:安静或醒目、密集或宽敞、严肃或活泼、几何或有机——不只是冷色或暖色。
- 颜色承载含义:灰色构建结构;颜色传达状态、操作、强调和身份。缺乏理由的颜色只是噪声。(克制——一种强调色,而不是五种——是一项方向原则;参见 design-thinking → 将视觉冲击留给点缀。)
- 对比度——用 APCA 辅助判断,用 WCAG 把关。 对于感知层面的对比度判断(这段文字在这个表面上是否易于阅读?),优先使用 APCA(apcacontrast.com)——它对亮度感知的建模远胜于 WCAG 2 比率,后者对深色背景上的浅色内容和中间调的评估并不准确。将 WCAG 2(4.5 / 3:1)作为合规底线——
design-spatial的layout-audit.js会以此作为门槛,可访问性标准也有此要求。APCA 可为设计提供参考,但要符合 WCAG,必须满足所有适用标准,而不只是对比度比率。 - 交互状态应增强对比度。
:hover、:active、:focus必须比静止状态更醒目:增加对比度,而非降低。降低对比度的悬停状态(例如让文字颜色变浅、接近背景色)看起来会像禁用状态。
避免通用或追逐潮流的风格(Inter、白底配紫色、千篇一律的暗色玻璃卡片)并在不同代设计中保持变化,属于 design-spatial §2——这里不再赘述。
背景与细节
氛围感胜过纯色填充——但应与所选美学风格相匹配,而不是套用默认方案。下意识采用渐变网格、噪点或颗粒的“高级感”处理,本身就是设计潮流的平均趋同现象(design-spatial §2);只有当设计方向确实需要时才使用,绝不要为了装饰而添加。
示例
用户请求:
使用 @design-system 评审此界面,找出影响最大的设计问题,并提出可直接实施的改进方案。
限制
- 仅当任务与其上游来源及本地项目上下文明确匹配时,才使用此技能。
- 应用更改前,验证命令、生成的代码、依赖项、凭据和外部服务行为。
- 不要将示例视为环境特定测试、安全审查,或对破坏性或高成本操作征求用户批准的替代品。
可访问性与回退要求
确保关键文本始终可见,并提供易读的回退方案以及故障/无 JavaScript 时的替代路径;字体加载不得延迟用户访问任务,也不得导致可聚焦控件不可见。字体转换/自托管需获得许可证许可,且不能保证节省固定字节数或呈现效果完全相同。在可访问的展开方式或等效的可见详细信息中保留完整状态/错误文本;在缩放、窄屏或本地化场景下,不要截断关键信息。尊重所有用户的减少动态效果偏好,避免在过渡期间隐藏信息,并为粘性滚动叙事提供静态且可通过键盘访问的叙述替代方案。仅进行对比度审查不足以证明符合 WCAG:还需测试键盘/焦点、语义、重排、文本替代内容及其他适用标准。本仓库不包含外部设计辅助组件和布局审查工具;调用前请确认其是否可用。