关于 designing-frontend-interfaces
面向编码 Agent 的前端界面设计技能,要求先定义设计简报与设计令牌,再构建组件,并通过视觉检查和自评确保风格一致。
主要功能
- 01先写 8 行设计简报
- 02建立 CSS 设计令牌系统
- 03按步骤构建布局与组件
- 04检查交互元素的五种状态
- 05渲染截图并按标准自评
适用场景
- 01开始构建新的前端界面
- 02为界面确定配色与排版体系
- 03检查交互状态和视觉呈现
- 04依据评审清单改进现有界面
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ osmontero/ opencode-skills --skill designing-frontend-interfaces安装后在 Claude Code 中输入/designing-frontend-interfaces确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.txtreferences/aesthetic-directions.mdcolor-and-theme.mdlayout-and-composition.mdmotion.mdtypography.md详细介绍
设计前端界面
概述
与众不同的界面源于坚定选择一种美学方向,并用一套固定的价值体系将其贯彻到底。千篇一律的界面,则源于需要什么值就临时选什么值。
核心原则: 编写组件之前,先确定设计体系。最终 CSS 中的每个数值,都应该能追溯到你精心选定的尺度。
这项技能涵盖视觉工艺。另外两项配套技能涵盖界面质量的其他方面:
- 对于包含流程、表单或复杂状态的内容,必需的子技能:使用
designing-user-experience - 发布之前,必需的子技能:使用
building-accessible-interfaces - 如需评审完成的 UI,请使用
reviewing-interface-quality
铁律
NO COMPONENT CODE BEFORE THE DESIGN BRIEF AND TOKEN BLOCK EXIST
设计简报只有 8 行。令牌块只有一个 CSS 代码块。两者合计只需大约 90 秒,却能让精心设计的界面与单纯装饰过的界面判然有别。
已经先写了组件?那这些值已经是随意定的。继续之前,先将它们整理成真正的尺度——不要为碰巧输入的数值找理由。
检查清单
为每项创建任务,并按顺序完成:
- 撰写设计简报——8 行,在你的回复中撰写,且要在创建任何文件之前
- 选择美学方向——从
references/aesthetic-directions.md中选择,或自行构思,并为其命名 - 锁定令牌块——字号比例、颜色阶梯、间距尺度、圆角、阴影、动效。一个 CSS 代码块。
- 搭建布局骨架——只处理结构和间距,暂不添加装饰
- 构建组件——每个交互元素都要具备全部五种状态
- 添加一个令人难忘的亮点——唯一值得人们记住的设计元素
- 依据评估标准自查——见下文的“自查”;修复不合格之处
- 目视验证——渲染出来,并亲自查看
步骤 1:设计简报
创建任何文件之前,先写好这段内容。它是你在回复中写的 8 行纯文本——不是文档,也不是文件。
Purpose: What job does this interface do?
Audience: Who uses it, in what context, on what device?
Tone: One named direction (see references/aesthetic-directions.md)
Reference: A real-world visual analogue — a magazine, a era, a discipline
Palette: Base / surface / ink / one accent — as hue intentions, not hex yet
Type: Display face + text face, and why this pairing
Memorable: The one thing someone will describe to a friend
Restraint: What this design deliberately does NOT do
Restraint 这一行最重要。没有明确写出克制原则的设计,最后往往会把所有效果一次用上。
完整示例:
Purpose: Changelog for a developer infrastructure tool
Audience: Engineers skimming on a wide monitor, 30 seconds per visit
Tone: Technical Broadsheet — newspaper density meets terminal precision
Reference: Financial Times print edition, 1990s man pages
Palette: Warm newsprint base, near-black ink, one signal red for breaking changes
Type: Instrument Serif display / IBM Plex Mono text — editorial authority, machine detail
Memorable: Version numbers set enormous in the left margin, hanging outside the text column
Restraint: No cards. No shadows. No rounded corners. Rules and space only.
步骤 2:锁定令牌块
界面使用的每个值都从这里定义。如果某个数值不在此代码块中,就不应出现在组件里。
:root {
/* TYPE — one ratio, applied consistently. 1.200 minor third (dense UI),
1.250 major third (general), 1.333 perfect fourth (marketing),
1.500 perfect fifth (editorial/poster). Pick ONE. */
--font-display: "Instrument Serif", Georgia, serif;
--font-text: "IBM Plex Mono", ui-monospace, monospace;
--step--1: 0.833rem; --step-0: 1rem; --step-1: 1.25rem;
--step-2: 1.563rem; --step-3: 1.953rem; --step-4: 2.441rem;
--step-5: 3.052rem; --step-6: 3.815rem;
/* SPACE — one base unit and its multiples. Never a value in between. */
--space-3xs: 0.25rem; --space-2xs: 0.5rem; --space-xs: 0.75rem;
--space-s: 1rem; --space-m: 1.5rem; --space-l: 2rem;
--space-xl: 3rem; --space-2xl: 4.5rem; --space-3xl: 7rem;
/* COLOR — a ramp, not a set of one-offs. One accent, used sparingly. */
--base: #f4f1ea; /* page */
--surface: #ffffff; /* raised */
--ink: #12100e; /* primary text */
--ink-2: #55504a; /* secondary text */
--ink-3: #8b857c; /* tertiary / meta */
--line: #ddd7cc; /* borders, rules */
--accent: #c1362f; /* <10% of visible surface */
/* FORM */
--radius: 0; /* commit: 0, or 2-4px, or a full 999px pill. Not "some of each". */
--border: 1px solid var(--line);
--shadow: none; /* if using shadows, define 2 — near and far. Never 5. */
/* MOTION */
--dur-fast: 120ms; --dur: 220ms; --dur-slow: 420ms;
--ease: cubic-bezier(0.2, 0, 0, 1);
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}
代码块规则:
| 令牌 | 规则 |
|---|---|
| 字号比例 | 整个页面只使用一个比例。凭感觉调整字号会让层级变得含混。 |
| 间距尺度 | 每个外边距/内边距/间隙都必须是一个 --space-* 令牌。不能用 13px,也不能用 0.85rem。 |
| 颜色阶梯 | 三个墨色层级就够了。需要第四个,说明层级不清晰。 |
| 强调色 | 除非美学方向明确追求极繁主义,否则只能用一种。占表面面积不到 10%。 |
| 圆角 | 只用一个值。混用圆角是最明显的业余设计信号。 |
| 阴影 | 用零个或两个。两个阴影 = 一个紧贴物体的接触阴影 + 一个宽阔的环境阴影。 |
| 动效 | 三种时长、两种缓动。足以覆盖界面所需的所有过渡效果。 |
步骤 3:层级
每次只调整一个维度。 业余设计会同时改变大小、粗细、颜色和间距;结果就是处处都在抢眼,却没有重点。
| 需求 | 调整 | 保持不变 |
|---|---|---|
| 区块标题与正文的区分 | 大小(至少跨 2 个级别) | 粗细、颜色 |
| 段落内的强调 | 粗细 | 大小、颜色 |
| 元信息/说明文字 | 颜色(设为 --ink-3) | 大小、粗细 |
| 分组 | 间距(增减一个完整级别) | 其他所有项 |
间距比线条或方框更能可靠地划分分组。 添加边框或卡片之前,试着将组与组之间的间距加倍,并将组内间距减半。大多数“需要卡片”的直觉,其实是“需要合适的间距”。
步骤 4:反套路
通用 AI 界面输出有一套明确且可枚举的特征。这些不是风格偏好,而是让输出一眼就能被识别的默认做法。
| 不要这样做 | 应改为 |
|---|---|
将 Inter、Roboto、Arial、system-ui 用作展示字体 | 选一种有个性的字体——参见 references/typography.md |
| 在白色背景上使用紫色/紫罗兰到蓝色的渐变 | 参考真实范例,选定真正的配色方案 |
所有元素都使用 rounded-lg / rounded-xl | 选定一种圆角值,或完全不使用圆角 |
每个表面都加上 shadow-md | 只在元素确实呈浮起效果时使用阴影 |
| 主视觉 → 3 张功能卡片 → CTA | 让内容决定结构 |
整页都使用居中的 max-w-4xl 栏 | 根据内容类型调整行宽;至少有一处打破网格 |
白色背景上使用 text-gray-500 正文 | 有意选用真正的墨色;正文使用足够高的对比度 |
| 用 Emoji 代替图标 | 使用真正的图标集,或者不使用图标 |
| 使用同一种中性无衬线字体的六种字重 | 最多使用两种字体、三种字重 |
| 每个区块都采用相同的垂直节奏 | 调整各区块的间距,以体现重要程度 |
趋同陷阱: 在不同的生成任务中,不要总是选择相同的“安全且有特色”的方案。Space Grotesk、深石板色背景和青柠绿点缀如今本身也成了陈词滥调。不同设计之间要变换明暗、衬线/无衬线/等宽字体,以及紧凑或疏朗的布局。查看 references/aesthetic-directions.md,选一个上次没有选过的方向。
自我说服表:
| 想法 | 事实 |
|---|---|
| “用户没指定风格,所以中性最稳妥” | 未指定就由你来选。中性也是一种选择,而且是最糟糕的选择。 |
| “这只是一个快速演示” | 人们看的正是演示。需求简报只要九十秒就能读完。 |
| “Inter 确实是款好字体” | 没错。但它也是通用 AI 风格最明显的信号。正文最多可以用它,展示字体绝不能用。 |
| “卡片网格是展示功能最清晰的方式” | 这是最常见的方式。试试表格、带分隔线的列表、阶梯式布局或编辑式排版。 |
| “我最后再添加有特色的细节” | 独特性是结构性的。最后硬加上去只会显得像装饰。 |
| “Tailwind 默认值就是一套设计系统” | 它们只是默认值的调色板。要么进行配置,要么就会和所有人一样照搬默认值。 |
步骤 5:组件状态
每个交互元素都必须具备全部五种状态。缺少状态是生成式 UI 中最常见的问题。
.btn { /* rest */ }
.btn:hover { /* pointer only — must not be the sole affordance */ }
.btn:active { /* pressed — a real transform, not just a color shift */ }
.btn:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }
.btn:disabled { /* visibly inert, and still readable */ }
.btn[aria-busy] { /* loading — reserve the space, don't collapse the layout */ }
绝不要移除焦点轮廓。如果默认轮廓不好看,就重新设置样式——不要设置 outline: none。参见 building-accessible-interfaces。
步骤 6:视觉验证
渲染代码并回头阅读,并不算验证。要查看实际像素。
# Static HTML
python3 -c "
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
b = p.chromium.launch()
pg = b.new_page(viewport={'width':1440,'height':900})
pg.goto('file:///abs/path/index.html'); pg.wait_for_timeout(600)
pg.screenshot(path='/tmp/desktop.png', full_page=True)
pg.set_viewport_size({'width':390,'height':844})
pg.screenshot(path='/tmp/mobile.png', full_page=True)
b.close()"
然后读取两张 PNG,并根据评分标准进行检查。对于开发服务器,请使用 testing-webapps 技能中的 with_server.py 辅助工具。
只有在渲染结果中才能发现的问题: 文本溢出容器、布局在 390px 宽度下崩塌、低对比度文本不可见、元素贴着视口边缘、标题换行后只剩一个词,以及缺少尺寸的图像导致布局偏移。
自我检查
如实为每一项评分。任何一项为 no 都意味着要修复,而不是解释。
- CSS 中的每个间距值都来自代码块中的设计令牌
- 字号比例只采用一个比例;没有任何字号是凭感觉选的
- 恰好使用一种强调色,且占可见表面的比例低于 10%
- 全程使用一种圆角值
- 陌生人只看截图就能说出美学方向
- 需求简报中的
Memorable一项确实体现在成品中 - 确实遵循了
Restraint一项的要求 - 反套路表中的做法一个都没有出现
- 每个交互元素都具备全部五种状态
- 焦点清晰可见,且从未被隐藏
- 通过查看截图,在 1440px 和 390px 下完成验证
- 正文文本对比度达到 4.5:1;大号文本达到 3:1
参考文件
在需要做出相关决策时再加载这些文件——不要提前加载。
| 文件 | 加载时机 |
|---|---|
references/aesthetic-directions.md | 步骤 1——选择并设定方向参数 |
references/typography.md | 选择字体、构建字号阶梯、设置文本 |
references/color-and-theme.md | 构建色阶、深色模式、对比度计算 |
references/layout-and-composition.md | 网格、断点、打破网格、z-index |
references/motion.md | 除悬停颜色变化之外的任何动画 |
常见错误
声明了令牌,却没有使用。 :root 块确实存在,但组件用的是 padding: 14px。完成前,用 grep 搜索 CSS 中的原始 px 值。
字体有特色,其他一切却千篇一律。 把 Inter 换成展示字体,却保留卡片网格、统一圆角和灰色正文,只会让产出显得像穿了戏服的普通设计。
把极繁主义当作缺乏连贯性的借口。 极繁主义方向仍需要一套字号阶梯、一套间距阶梯和一套配色。元素更多,系统不变。
设计简报描述的设计与实际构建不符。 在步骤 7 重新阅读简报。如果 Restraint: no shadows,而构建结果却有阴影,那就是构建错了。
复杂度与设计愿景不匹配。 用复杂的滚动动画实现精致极简风格,会显得令人困惑。让实现投入与所述风格基调相匹配。