mcpField
S
surface

surface

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

关于 surface

surface 是用于设计界面颜色、表面层级和明暗主题的设计技能。它为产品界面提供语义令牌、对比度、强调色和主题切换方面的指导。

主要功能

  1. 01定义语义颜色令牌
  2. 02构建协调的明暗主题调色板
  3. 03设定表面层级与边框
  4. 04规范对比度和状态颜色
  5. 05配置主题切换与焦点样式

适用场景

  1. 01创建支持明暗主题的配色系统
  2. 02检查文本和控件对比度
  3. 03统一卡片与弹出层表面样式

安装

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

$npx skills add https://github.com/paragonhq/stealth-skills --skill surface

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

详细介绍

表面

界面中的颜色大多意味着没有颜色。把中性色和层级关系处理好,一种强调色就足够了。

先定义令牌

按用途命名颜色,绝不要按数值命名。能适用于两种主题的调色板大致如下:

令牌用途
--page最外层背景,位于应用框架之后
--frame应用表面
--raised卡片、弹出层以及所有高出一层的元素
--hover行和项目的悬停填充色
--line默认边框
--line-2更醒目的边框、焦点环以及必须清晰可见的分隔线
--fg主要文本和图标
--fg-2次要文本
--fg-3三级文本、元信息、占位符
--fg-4微弱元素:装饰、禁用状态、文本中的分隔线
--accent只用一种。用于主要操作和焦点,其他地方一概不用
--ok、--warn、--danger状态色,采用柔和色调,并分别提供适用于文本的变体

其他一切都由此派生。组件绝不直接引用十六进制颜色,而是引用令牌。深色模式是同一组令牌的第二套取值,而不是第二套组件。

中性色

始终使用略带暖调或冷调的近黑色和近白色。纯 #000 和 #fff 过于生硬;深色主题采用 #080808 搭配 #ededed 的文本,会显得经过精心设计,而 #000/#fff 则像是尚未设置。

一套可行的深色值:

page #080808 · frame #0d0d0d · raised #141414 · hover #161616
line #1c1c1c · line-2 #262626
fg #ededed · fg-2 #9b9b9b · fg-3 #6b6b6b · fg-4 #454545

浅色值:

page #f2f2f0 · frame #fbfbfa · raised #ffffff · hover #f1f1ef
line #ebebe8 · line-2 #dcdcd8
fg #151515 · fg-2 #5f5f5c · fg-3 #8d8d89 · fg-4 #b8b8b3

色阶有意设置得很细微。表面的亮度差异为 2–4%,足以让眼睛区分它们,又不会显得条纹分明。截屏后眯起眼睛观察:你应该看到结构,而不是杂乱的色块。

生成中性色时,使用 OKLCH 来构建,这样色阶在视觉上均匀,且色相不会随着亮度变化而改变。

深色模式不是反转后的浅色模式

  • 浅色模式用阴影提升元素。深色模式用更亮的表面和边框提升元素。在 #0d0d0d 上,阴影不可见。
  • 深色表面的顶部添加 1px 内嵌高光,白色不透明度为 4%,让表面看起来像是从上方受光:box-shadow: 0 1px 0 rgba(255,255,255,.04) inset。
  • 高饱和度的颜色在深色背景上会发光。深色模式下,将强调色的饱和度降低 10–20%,并降低其亮度。
  • 纯黑上的纯白文本会刺眼。两者都应调柔和。
  • 图片和插画可能需要轻微变暗(opacity: .9)或提供深色模式专用版本。
  • 在根元素上设置 color-scheme: dark,让表单控件、滚动条和浏览器界面保持一致。

边框与阴影

主题卡片 / 弹出层边缘
深色border: 1px solid var(--line-2) + 内嵌高光;只有浮动层使用柔和的外阴影:0 12px 40px -12px rgba(0,0,0,.9)
浅色box-shadow: 0 1px 0 rgba(255,255,255,.9) inset, 0 12px 32px -14px rgba(0,0,0,.18);只有表面与其所在背景颜色相同时才使用边框

阴影只用一层,柔和且带负扩展,方向与单一光源一致。绝不用 0 0 20px(光晕),绝不用多层模糊叠加,也绝不在产品界面中使用彩色阴影。

边框为 1px。不要用 0.5px(渲染效果不一致),除焦点环外也不要用 2px。

Alpha

叠加层、悬停填充色和未知背景上的分隔线使用 Alpha 值,这样它们能适用于任何表面:

  • 悬停填充:前景色不透明度为 4–6%
  • 按下填充:前景色不透明度为 8–10%
  • 分隔线:前景色不透明度为 8–12%
  • 对话框后方的背景遮罩:页面颜色不透明度为 60–70%,并且 backdrop-filter: blur(4px) 最多只用到这个程度
  • 玻璃表面(backdrop-filter)开销较大;每个屏幕最多用一个,不要动画,也不要嵌套

强调色

只用一种色相。它用于主要按钮;当中性色焦点环不够醒目时,也用于焦点环;还用于行内文本链接和控件的激活状态。不要用于图标、标题、边框、背景或徽章。

如果所有东西都是强调色,那就等于没有强调色。数一下屏幕上使用强调色的元素;如果超过三个,就删掉一些。

状态色应柔和(绿色的色度约为 55%,而不是交通信号灯般鲜艳),并且始终搭配文字或图标。颜色绝不是唯一的提示方式。

对比度

  • 正文和次要文本:与其表面的对比度至少为 4.5:1。
  • 大号文本(18px 以上或 14px 以上的粗体文本)和 UI 边界(图标、输入框边框):对比度至少为 3:1。
  • 只有在使用界面时不需要依赖三级文本的情况下,其对比度才可以低至 3:1。
  • 淡显(--fg-4)仅用于装饰,绝不能承载信息。
  • 两种主题都要检查。在白色背景上通过的灰色,在 #0d0d0d 上可能就无法通过。

如果占位符是唯一的标签,就要将其视为文本;此时必须达到对比度要求。更好的做法是始终显示可见标签。

渐变、噪点、纹理

产品 UI:不使用渐变,或者只在主视觉区域背后使用一个非常柔和的径向渐变,以 2% 的不透明度为页面营造光源效果。营销页面:可以使用,但仍只用一个。

渐变上叠加噪点或抖动纹理,可以隐藏色带并增加质感;不透明度保持在 3–6%,并使用平铺的小型 SVG,而不是大型 PNG。

背景图案(网格、刻度、点)采用 --line 级别的颜色,置于框架后方并在边缘处停止;绝不能延伸到内容下方。

选中状态、焦点、滚动条

::selection { background: var(--fg); color: var(--frame); }
:focus-visible { outline: 1px solid var(--fg-2); outline-offset: 2px; }
* { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }

这三处决定了应用是经过主题设计的,还是仅仅套用了主题。

切换主题

  • 在首次绘制前,通过内联脚本读取存储值和 prefers-color-scheme 来确定主题。错误主题一闪而过也是 Bug。
  • 保存用户的选择;如果用户没有选择,则遵循系统设置。
  • 在根元素上对 background-color 使用约 400ms 的过渡效果,避免切换时闪烁。或者使用视图过渡,从切换控件处揭示新主题;无论采用哪种方式,在减少动态效果模式下都应立即切换。
  • 两种主题都应得到充分支持。如果团队只关注深色主题,浅色主题就会逐渐失修,反之亦然。两种主题都要检查。

廉价表面的特征

特征改进方法
#000 页面、#fff 文本使用 #080808 / #ededed
卡片同时有边框、阴影和不同的背景色三者选一,最多选两种
发光阴影(0 0 24px accent)使用柔和的定向阴影,或不加阴影
每张卡片都使用不同的色调使用同一个表面令牌
灰色文本的对比度为 2.5:1,“因为看起来更浅”使用通过对比度检查的 --fg-2;通过字号和字重体现层级
渐变按钮使用纯色填充;次要按钮仅使用边框,三级按钮使用幽灵样式
深色模式沿用浅色模式的阴影使用边框和内侧高光

目录精选

评论

支持 Markdown