better-ui

better-ui

热门

设计工程原则,让界面感觉更精致。在构建UI组件、审查前端代码、实现动画、悬停状态、阴影、边框、微交互、进入/退出动画、选择或审查图标,或任何视觉细节工作时使用。触发条件:UI打磨、设计细节、“让它感觉更好”、“感觉不对劲”、交错动画、边框半径、光学对齐、图像轮廓、盒阴影、图标、图标描边粗细、图标状态、动效克制。

1291Star
32Fork
更新于 2026/7/28
SKILL.md
readonly只读
name
better-ui
description

设计工程原则,让界面感觉更精致。在构建UI组件、审查前端代码、实现动画、悬停状态、阴影、边框、微交互、进入/退出动画、选择或审查图标,或任何视觉细节工作时使用。触发条件:UI打磨、设计细节、“让它感觉更好”、“感觉不对劲”、交错动画、边框半径、光学对齐、图像轮廓、盒阴影、图标、图标描边粗细、图标状态、动效克制。

让界面感觉更好的细节

优秀的界面很少来自单一因素。通常是许多小细节的累积,共同构成出色的体验。在构建或审查UI代码时应用这些原则。

审查时,放慢界面速度:在浏览器的动画面板中以10%速度重放动画,并遍历每个状态:悬停、聚焦、激活、加载、空状态。在10%速度下感觉不对劲的地方,就是全速时微妙出错的地方。

保留项目的组件库、标记和密度。匹配其已建立的动效语言,除非以下原则规定了精确的交互模式。

排版(文本换行、字体渲染、表格数字、间距)由 better-typography 技能覆盖;文本相关事项请使用该技能。可访问性(点击区域、聚焦状态、键盘支持、ARIA、减少动效)由 better-accessibility 技能覆盖。布局结构(分组、区块间间距、断点、空间RTL)由 better-layout 技能覆盖。

快速参考

类别 使用场景
表面 边框半径、光学对齐、阴影、图像轮廓
动画 可中断动画、进入/退出过渡、图标动画、按压缩放、动效克制
图标 图标描边粗细、通过 currentColor 的状态、轮廓与填充、尺寸、RTL翻转
性能 过渡属性指定、will-change 的使用

核心原则

1. 同心边框半径

外半径 = 内半径 + 内边距。嵌套元素半径不匹配是让界面感觉不对劲的最常见原因。

2. 光学对齐优先于几何对齐

当几何居中看起来不对时,进行光学对齐。带图标的按钮、播放三角形和不对称图标都需要手动调整。

3. 阴影用于层次,边框用于结构

对于按钮、卡片和容器,如果边框仅用于制造深度,优先使用多层透明 box-shadow 值。保留用于传达结构或状态的边框:分隔线、布局分隔符以及选中或聚焦状态。

4. 可中断动画

对交互状态变化使用CSS过渡:它们可以在动画中途被中断。将关键帧保留给一次性执行的阶段性序列。

5. 拆分并交错进入动画

对于不频繁的阶段性进入,且顺序有助于传达层次时,将内容拆分为语义块,并交错约100毫秒,而不是动画化单个容器。不要对常规、高频交互进行交错。

6. 微妙的退出动画

使用小的固定 translateY 而不是完整高度。退出应比进入更柔和。进入和退出过渡都使用 ease-out

7. 上下文相关的图标动画

使用 opacityscaleblur 动画化图标,而不是切换可见性。精确使用这些值:缩放从 0.251,透明度从 01,模糊从 4px0px。如果项目在 package.json 中有 motionframer-motion,匹配该包的导入路径(或两者都存在时使用已建立的附近导入),并使用 transition: { type: "spring", duration: 0.3, bounce: 0 };bounce 必须始终为 0。如果没有安装动效库,将两个图标都保留在DOM中(一个绝对定位),并使用CSS过渡交叉淡入淡出,使用 cubic-bezier(0.2, 0, 0, 1);这样无需任何依赖即可实现进入和退出动画。

8. 图像轮廓

为图像添加微妙的 1px 低透明度轮廓,以保持一致的深度。颜色在浅色模式下必须是纯黑色(oklch(0 0 0 / 0.1)),在深色模式下必须是纯白色(oklch(1 0 0 / 0.1)),绝不能使用接近黑色的颜色,如石板色、锌色或任何带色调的中性色。带色调的轮廓会吸收其下方的表面颜色,在图像边缘看起来像污垢。

9. 按压缩放

点击时微妙的 scale(0.96) 为按钮提供触觉反馈。始终使用 0.96。切勿使用小于 0.95 的值:任何低于此的值都会感觉夸张。添加 static 属性以在动效会分散注意力时禁用它。

10. 页面加载时跳过动画

AnimatePresence 上使用 initial={false} 以防止首次渲染时的进入动画。验证它不会破坏有意的进入动画。

11. 绝不使用 transition: all

始终指定精确属性:transition-property: scale, opacity。Tailwind 的 transition-transform 覆盖 transform, translate, scale, rotate

12. 谨慎使用 will-change

仅用于 transformopacityfilter,这些是GPU可以合成的属性。绝不使用 will-change: all。仅在注意到首帧卡顿时添加。

13. 图标描边与文本粗细匹配

文本旁边的图标承载文本的光学重量:1.5px 描边对应常规(400)文本,2px 对应半粗(600)。每个图标集使用一种描边粗细;切勿在同一表面混合使用不同库。

14. 一个SVG,按状态重新着色

图标使用 currentColor,其状态(悬停、选中、禁用)通过CSS颜色和透明度实现,绝不使用单独的素材。轮廓变体为默认,填充变体标记激活状态。

15. 动效克制

高频交互上不要使用自定义动画:每次触发都会重复注意力成本。动效绝不是唯一的反馈渠道;每个动画状态变化还需要一个静态提示(颜色、图标、标签)。

常见错误

错误 修复
紧密嵌套的父元素和子元素使用相同的边框半径 计算 outerRadius = innerRadius + padding
图标看起来不居中 通过内边距或直接修复SVG进行光学调整
仅用于伪造层次的边框 使用带透明度的分层 box-shadow;保留结构性和状态边框
突兀的阶段性进入或上下文退出 交错不频繁的进入,并保持保留上下文的退出微妙
有状态的图标或切换在页面加载时动画化其默认状态 向该 AnimatePresence 添加 initial={false};保留有意的页面进入
元素上的 transition: all 指定精确属性
首帧动画卡顿 添加 will-change: transform(谨慎使用)
粗体文本旁的极细图标 将描边宽度与文本粗细匹配
每个状态使用单独的图标素材 一个 currentColor SVG,状态通过CSS实现
到处使用填充图标 轮廓为默认,仅激活状态使用填充
每次悬停或按键时都有进入动画 即时反馈或≤150ms的透明度/颜色过渡

审查输出格式

仅当用户要求独立的UI打磨审查时使用此格式。当 better-interface 协调审查时,向该技能提供领域证据和发现,并让其输出格式、严重性等级、合并规则、上限和结论优先。

以两部分呈现独立审查。

发现

按原则分组所有确认的发现。使用带有严重性位置之前之后原因列的Markdown表格。绝不使用单独的“之前:”/“之后:”行。

  • 严重性HIGH 使交互误导、无响应或反复干扰;MEDIUM 造成明显的工艺或一致性问题;LOW 是孤立的打磨问题。
  • 位置:引用 path/to/file:line。如果工件没有源文件,引用确切的屏幕和组件。
  • 之前/之后:显示当前实现和可操作的替换方案。
  • 原因:指出违反的原则并解释它如何影响界面。

将重复的系统性问题合并为一行,并列出每个受影响的位置。省略没有发现的原理。

示例

同心边框半径
严重性 位置 之前 之后 原因
LOW src/Card.tsx:28 卡片 rounded-xl + 内部按钮 rounded-xlp-2 卡片 rounded-2xl8 + 8 = 16),内部按钮 rounded-lg 嵌套角应为同心
LOW src/card.css:11 两个嵌套表面均为 border-radius: 16px 外部 24px,内部 16px,内边距 8px 相等的嵌套半径使内部表面看起来被挤压
按压缩放
严重性 位置 之前 之后 原因
LOW src/Button.tsx:19 <button className="..."> 添加 active:scale-[0.96] transition-transform 按压反馈使控件感觉响应灵敏
MEDIUM src/button.css:24 按压时 scale(0.9) 提高到 scale(0.96) 任何低于 0.95 的值都会感觉夸张

验证与结论

在发现之后:

  1. 验证:列出执行的确切检查及其观察结果。遍历每个相关状态,并在涉及动画时以10%速度检查动效。如果某项检查未执行,说明仍需验证的内容。
  2. 结论:如果存在任何 HIGH 发现,则为 Block;如果仅存在 MEDIUMLOW 发现,则为 Needs changes;仅当没有可操作的发现时,才为 Approve

当没有发现时,省略表格,说明“无可操作的UI打磨发现”,报告验证,并以 Approve 结束。