mcpField
B
better-ui

better-ui

github.com/jakubkrehel设计与 UI9.0k40.6k 次安装3 天前更新
代码仓库

关于 better-ui

better-ui 是用于检查和完善界面表面、图标与动效的设计技能,适用于交互已正常工作的界面。它提供具体样式规则,并按严重程度组织界面细节问题的报告。

主要功能

  1. 01表面圆角与阴影规则
  2. 02图标对齐和颜色状态指引
  3. 03过渡与动效规范
  4. 04减少动态效果及悬停行为
  5. 05界面问题分级与报告格式

适用场景

  1. 01审查组件动效和交互状态
  2. 02检查图标与表面的一致性
  3. 03按严重程度报告界面细节问题

安装

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

$npx skills add https://github.com/jakubkrehel/skills --skill better-ui

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

包含的文件

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

animations.md
enter-exit.md
icon-transitions.md
icons.md
performance.md
surfaces.md
agents/
openai.yaml

详细介绍

UI 润色

这项技能涵盖界面、图标和动效的视觉润色,并为每个细节规定了精确取值。只有在底层交互正常后才应用;润色问题永远不能优先于交互故障。

精确取值,润色可选

以下取值都是精确值,不是供近似的范围。cubic-bezier(0.2, 0, 0, 1) 不等于 cubic-bezier(0.4, 0, 0.2, 1),0.96 也不等于 0.95。视觉微调和同心内边距阈值是例外,它们只是起点,应凭视觉判断。

遵循项目的组件库、设计令牌和密度;如果这里没有规定取值,就沿用项目的动效风格。经过深思熟虑且始终一致的项目惯例,例如完全不使用阴影的风格,属于偏好,而非问题。同一项目中的同一细节有两种做法,则属于问题。

文本换行、字体渲染、等宽数字和文本间距属于 better-typography。点击区域、键盘支持、ARIA 和减少动态效果要求属于 better-accessibility。分组、区块间距、断点和空间方向 RTL 属于 better-layout,方向性图标镜像除外。颜色令牌和对比度测量属于 better-colors。

外层圆角等于内层圆角加内边距

如果嵌套表面具有相同且均匀的可见内缩,外层圆角应等于内层圆角加内边距,再加上任何边框宽度。内边距超过 24px,或刻意采用非对称内边距时,应将各层视为独立表面,并保留各自的圆角令牌。具体做法见 surfaces.md。

几何对齐看起来不自然时,采用视觉对齐

如果几何居中看起来不自然,就凭视觉微调。按钮图标一侧的内边距减少 2px,将播放三角形朝尖端方向移动,并直接在 SVG 中修正不对称字形。具体做法见 surfaces.md。

用阴影表现层级,用边框表现结构

如果边框只是为了营造深度,就用分层的透明 box-shadow 值替代。分隔线、分隔符、表格单元格和选中状态应保留边框。表单输入框也应保留边框,因为根据 better-accessibility,其边界需要达到 3:1 的非文本对比度。焦点环也属于 better-accessibility。

强制颜色模式会移除所有 box-shadow。在阴影环下保留 border: 1px solid transparent,以便该模式仍能绘制边缘。具体做法见 surfaces.md。

为图像添加纯黑或纯白描边

为内容图像添加向内缩进 1px 的 1px 描边。浅色模式使用 oklch(0 0 0 / 0.1),深色模式使用 oklch(1 0 0 / 0.1)。切勿使用调色板中的近黑色、带色调的中性色或强调色,否则图像边缘会出现彩色边缘。跳过 Logo 和插画等透明艺术图像。具体做法见 surfaces.md。

交互状态使用过渡,而非关键帧

使用 CSS 过渡或动效库的弹簧效果来驱动交互状态变化;当用户在动效进行中反向操作时,这些效果会重新设定目标。关键帧会按固定时间线运行且无法反向,因此只用于只播放一次的序列。请参阅 animations.md。

按下时缩放至 0.96

按钮按下时,应在 150ms 内以 ease-out 缩放至 0.96;禁用按钮则绝不缩放。如果动效会造成干扰,应通过组件现有的变体 API 或 static 属性为按钮提供退出选项。请参阅 CSS、Tailwind 和 Motion 的配方。

高频交互应即时响应

按键输入、行悬停和标签页切换应即时反馈,或在 opacity、background-color 上使用不超过 150ms 的过渡。富有表现力的动效应留给低频时刻,例如视图首次加载、成功状态或空状态。

每次动画状态变化也都应留下静态提示,例如颜色、图标或标签。动效绝不能是唯一的反馈方式。

仅在未启用减少动态效果时运行动效

better-accessibility 负责这项要求,所有配方都必须遵守。仅在 prefers-reduced-motion: no-preference 下运行移动、缩放和模糊效果。启用减少动态效果时,应改用不透明度交叉淡化,而不是立即移除元素。CSS、Tailwind 和 Motion 的配方见 animations.md。

低频入场动效之间间隔 100ms

在分阶段入场中,若顺序能够传达层级关系,就将内容拆分为标题、描述和操作等语义块。各块之间间隔 100ms,以不透明度、4px 模糊和 12px 的 translateY 动效入场,持续 300ms,使用 ease-out。绝不要为常规交互设置交错动效。参见 enter-exit.md。

退出动效应比入场动效更短、更小

退出时使用不透明度、4px 模糊和固定的 -12px translateY 动效,持续 150ms,使用 ease-out,绝不要使用整个容器的高度。只有在目标位置具有意义时,才完全滑出,例如关闭抽屉。若动效没有传递任何信息,则立即移除元素。参见 enter-exit.md。

首次渲染时跳过状态动效

在包裹状态切换的 AnimatePresence 上设置 initial={false},这样默认状态在挂载时就不会播放入场动效。对于有意设置的入场动效(例如交错入场的主视觉区),绝不要这样设置。参见 animations.md。

使用精确值对上下文图标进行交叉淡化

当低频状态变化导致图标切换时,例如从播放切换到暂停或从复制切换到已复制,应使用交叉淡化。缩放从 0.25 变为 1,不透明度从 0 变为 1,模糊从 4px 变为 0px。使用动效库时,采用 { type: "spring", duration: 0.3, bounce: 0 },并始终将 bounce 设为 0。不使用动效库时,让两个图标都保留在 DOM 中,并使用 cubic-bezier(0.2, 0, 0, 1) 在 300ms 内进行交叉淡化。

标签页图标切换和行悬停时显示的操作属于 高频交互应即时响应。这两种配方见 icon-transitions.md。

切换主题时停用过渡效果

停用主题切换期间的所有过渡效果,强制刷新样式,并在下一帧恢复过渡效果。否则,所有颜色过渡会同时触发,让切换效果变得模糊。参见配方。

仅过渡发生变化的属性

像 transition-property: scale, opacity 这样明确指定属性,绝不要使用 all。参见 performance.md。

在 will-change 中指定动画属性

只有在观察到首帧卡顿时才添加 will-change,并指定动画所用的属性:scale 对应 scale,transform 对应 transform。仅限用于变换属性、opacity 和 filter,绝不要使用 all。参见 performance.md。

仅对支持悬停的指针使用悬停效果

将仅用于悬停的样式放在 @media (hover: hover) 中。在触摸设备上,轻触后 :hover 会持续生效,看起来像卡住的选中状态。Tailwind 4 的 hover: 变体已在该查询下编译,Tailwind 3 则不会。如果控件自行绘制按压状态,请设置 -webkit-tap-highlight-color: transparent,避免默认的灰色闪烁叠加其上。

将滚动限制在覆盖层内

为可滚动的对话框、抽屉、菜单和侧面板设置 overscroll-behavior: contain,这样滚动到末尾后,页面底层不会跟着滚动。

让图标描边与文本字重匹配

图标渲染出的描边粗细应与旁边文本的字重相匹配,从字重 400 时的 1.5px 到字重 700 时的 2.5px。每个界面使用一个图标库。表格、尺寸和网格规则见 icons.md。

一个 SVG,按状态重新着色

图标使用 currentColor,并通过 CSS 颜色和不透明度呈现悬停、选中和禁用状态,不使用单独的资源。默认变体为描边,填充表示激活状态。在 dir="rtl" 下,仅镜像含义随阅读方向变化的图标。请参阅 icons.md。

完成前检查

检测项修复方法
带内边距的父元素和子元素使用相同的 rounded-* 或 border-radius将内边距加到外层圆角上
box-shadow: 0 0 0 1px 用作边框环,但旁边没有 borderborder: 1px solid transparent
img 上的 outline-slate-*、outline-zinc-* 或十六进制轮廓颜色outline-black/10 和 dark:outline-white/10
transition-all 或 transition: all指定发生变化的属性
在 :hover、.open 或其他切换类上设置 animation:对相同属性使用过渡
active:scale-95、scale-90 或低于 0.96 的 whileTap0.96
:active 缩放没有排除 :disabledenabled:active: 或 :not(:disabled):active
bounce: 设置为非 0 值bounce: 0
基础规则中的 opacity: 0 仅通过 animation 显示在 from 关键帧中设置隐藏状态,并使用 animation-fill-mode: both
translate、scale、filter 或 motion.* 动画没有 prefers-reduced-motion、motion-safe: 或 MotionConfig 防护添加防护,并在减少动态效果时交叉淡入淡出不透明度
颜色过渡加上主题切换,但没有 disableTransitionOnChange 或覆盖规则使用主题切换抑制方案
will-change: all,或在从未播放动画的元素上设置 will-change指定动画属性或删除该声明
图标 SVG 中的 fill="#..." 或 stroke="#..."currentColor
@media (hover: hover) 之外的纯 CSS :hover 或 Tailwind 3 hover:用媒体查询包裹
对话框、抽屉或菜单上的 overflow: auto 或 overflow-y-auto 没有 overscroll-behavioroverscroll-behavior: contain

报告

严重程度。 HIGH 表示会破坏交互,例如无法反向播放的关键帧切换,或在触屏设备上卡住的悬停状态。better-interface 的两个升级触发条件都属于此类,一经发现即为 HIGH。一个是忽略 prefers-reduced-motion 的动态效果,另一个是仅通过动态效果呈现的状态变化。MEDIUM 表示表面样式、图标或动态效果存在明显不一致。LOW 表示个别细节需要打磨。

验证。 没有浏览器时,请根据代码读取组件定义的所有状态,例如悬停、按下、选中、加载和空状态,并检查其持续时间和缓动方式。使用浏览器时,请逐一查看各状态,并在浏览器的 Animations 面板中以 10% 速度重放动态效果。将所有无法执行的检查报告为 Not verified。

格式。 按违规原则分组,按严重程度排序;每个根本原因占一行,并列出其出现的所有位置:

严重程度位置修复前修复后原因

位置 格式为 path/to/file:line。原因需指出违反的原则及对用户的影响。

若仍存在任何 HIGH,结尾写上 Block;否则写上 Approve,并在表格中保留其余待处理事项。不得对未检查的覆盖范围写 Approve。若没有需要报告的问题,请写明“没有可采取行动的 UI 润色问题”,并报告验证情况。

评论

支持 Markdown