关于 reviewing-interface-quality
这项实践型技能用于检查界面的视觉质量、行为和无障碍性。它要求依据桌面与移动端渲染证据,将问题整理为包含位置、原因和具体修复方式的发现。
主要功能
- 01基于桌面与移动端渲染取证
- 02检查一致性、排版与布局
- 03审查状态和交互行为
- 04检查无障碍、动效与性能
- 05按严重程度列出具体修复
适用场景
- 01发布前审查页面
- 02发现响应式布局缺陷
- 03检查交互状态与无障碍性
- 04将笼统的润色意见转为可执行修复
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ osmontero/ opencode-skills --skill reviewing-interface-quality安装后在 Claude Code 中输入/reviewing-interface-quality确认已加载。
详细介绍
审查界面质量
概述
“让它看起来更好”不是可执行的要求。界面质量问题都有具体成因——未严格执行的间距比例、同时在四个维度上变化的层级、从未设计过的状态——只有指出成因和修复方法,审查才有用。
核心原则: 每条问题都要指出位置、成因和明确的替换值。“间距感觉不对”不算问题。“.card 使用 padding: 14px,而其他部分都遵循 8px 比例——改为 var(--space-s)”才算。
配套技能: designing-frontend-interfaces(视觉)、designing-user-experience(行为)、building-accessible-interfaces(无障碍)。这项技能会对照这三项进行审查。
铁律
NO FINDING WITHOUT EVIDENCE YOU ACTUALLY GATHERED
审查界面意味着实际查看界面。阅读源码并推测其渲染效果不算审查——这样会漏掉审查要发现的那类问题:溢出、布局塌陷、文字不可见、布局偏移、状态异常。
撰写任何问题前的最低证据要求: 一张 1440px 的截图、一张 390px 的截图,以及你准备判定为不一致的内容的计算值。
检查清单
- 收集证据 — 在两种宽度下渲染,捕获 DOM 和计算样式
- 第 1 轮:第一印象 — 先看 5 秒,再开始分析
- 第 2 轮:系统一致性 — 产出最高的一轮
- 第 3 轮:排版
- 第 4 轮:布局与响应式
- 第 5 轮:状态与行为
- 第 6 轮:无障碍
- 第 7 轮:动效与性能
- 报告 — 按严重程度分级,每条都指出位置、成因和修复方法
第 1 步:收集证据
from playwright.sync_api import sync_playwright
URL = "http://localhost:5173" # or file:///abs/path/index.html
with sync_playwright() as p:
b = p.chromium.launch()
pg = b.new_page(viewport={"width": 1440, "height": 900})
errors = []
pg.on("console", lambda m: m.type == "error" and errors.append(m.text))
pg.goto(URL); pg.wait_for_load_state("networkidle")
pg.screenshot(path="/tmp/rev-desktop.png", full_page=True)
# Horizontal overflow — always a bug
print("OVERFLOW:", pg.evaluate("""() => [...document.querySelectorAll('*')]
.filter(e => e.getBoundingClientRect().right > document.documentElement.clientWidth + 1)
.slice(0, 10).map(e => e.tagName + '.' + e.className)"""))
# Every distinct value actually used — the consistency audit
for prop in ["font-size", "font-family", "border-radius", "box-shadow", "padding", "color"]:
vals = pg.evaluate("""(p) => [...new Set([...document.querySelectorAll('*')]
.map(e => getComputedStyle(e)[p]))].filter(v => v && v!=='none' && v!=='0px')""", prop)
print(f"{prop}: {len(vals)} distinct →", vals[:14])
pg.set_viewport_size({"width": 390, "height": 844})
pg.screenshot(path="/tmp/rev-mobile.png", full_page=True)
print("CONSOLE ERRORS:", errors)
b.close()
然后查看两张截图。不同值的数量能告诉你系统在哪些地方出现了问题;截图能告诉你界面看起来如何。两者缺一不可。
对于由服务端支持的应用,请使用 testing-webapps/scripts/with_server.py 封装此步骤。
如果 UI 确实无法渲染(没有运行时、只有代码片段、组件独立存在),请在报告中明确说明,并将每条视觉问题标记为 PLAUSIBLE,而非 CONFIRMED。
第 2 步:第一印象
先看桌面截图 5 秒,再回答以下问题,然后才开始分析:
- 这是什么? 如果 5 秒内看不明白,说明层级设计失败。
- 我该做什么? 主要操作应该一目了然。
- 我的视线首先落在哪里? 那是最重要的内容吗?
- 我能说出它的美学方向吗? “简洁”和“现代”意味着没有明确方向。
- 我会猜这是生成的吗? 如果会,请指出具体的生成痕迹。
继续之前,请写下这些答案。一旦开始审查细节,你就无法还原最初的直观印象,而真实用户看到的正是这种印象。
第 3 步:系统一致性
产出最高的一轮。多数“看起来不够精致”的问题都出在这里,而且每条问题都有客观依据。
| 检查项 | 阈值 | 常见原因 |
|---|---|---|
不同的 font-size 值 | > 8 | 字号随意选取,没有比例体系 |
不同的 font-family 值 | > 3 | 混入了第三种字体,或回退字体解析结果不一致 |
不同的 border-radius 值 | > 2 | 圆角不统一——最明显的业余信号 |
不同的 box-shadow 值 | > 3 | 每个组件都发明了一种新阴影 |
| 偏离间距比例的内边距值 | 任意 | 使用原始 px 值,而不是设计令牌 |
color 中不同的灰色 | > 5 | 没有墨色阶;每个组件各自挑选灰色 |
| 强调色的表面占比 | > 10% | 把强调色当作装饰,而不是强调手段 |
# Fast static pass over source
grep -rEo '(padding|margin|gap|font-size):[^;]+' src/ | grep -E '[0-9]+px' | sort | uniq -c | sort -rn
grep -rEo 'border-radius:[^;]+' src/ | sort | uniq -c
还要检查: 是否声明了设计令牌却没有使用?:root 块中定义了漂亮的比例体系,组件里却充斥着原始 px 值——这是很常见且很容易修复的问题。
第 4 步:排版
- 尺寸遵循统一比例,而非凭感觉调整
- 展示字体不是 Inter / Roboto / system-ui
- 字重最多三种
- 正文行宽为 60-75ch,而非占满整页宽度,也非 30ch
- 行高随字号增大而减小(正文约为 1.6,展示文字约为 1.0)
- 大号展示文字使用负字距
- 正文不额外增加字间距
- 段落不居中;句子不全部使用大写字母
- 数字列使用
tabular-nums - 标题使用
text-wrap: balance - 标题末行没有孤立的单个词语
第 5 步:布局与响应式设计
- 任意宽度下页面都不会横向滚动(检查 overflow 查询的输出)
- 除非有意设置内边距,否则内容不会紧贴视口边缘
- 相关项之间的距离明显小于不相关项之间的距离(内外间距比为 4:1)
- 区块间距随重要性变化,而非整页一律相同
- 对齐方式一致,不出现差一点就对齐的情况(如左边缘相差 12px 与 16px)
- 在 390px 宽度下:没有重叠、文本没有被裁切,也没有固定元素遮挡内容
- 表格和代码块在各自容器内滚动,而非让整个页面滚动
- 图片设置了
width/height或aspect-ratio,不会造成布局偏移 - 使用
100dvh/100svh,而非100vh - 网格至少有一处经过有意打破,或设计采用统一居中的单列布局
第 6 步:状态与行为
逐项对照 designing-user-experience 检查。这些问题通常是缺失,而非错误——因此要审查代码,而不只是查看渲染结果。
- 区分空状态(首次使用)、空状态(无结果)和空状态(已清空)
- 加载时不会清空已显示的内容
- 骨架屏与实际内容形状一致,且延迟约 200ms 显示
- 错误提示说明应采取的操作,并提供相应控件
- 不向用户显示原始状态码或堆栈跟踪
- 表单出错时保留输入内容
- 在失去焦点时验证,而非每次按键时验证
- 输入框具有正确的
type、inputmode、autocomplete - 按钮标签明确说明其操作,脱离上下文也能看懂
- 破坏性操作提供撤销选项或具体的确认提示
- 五种交互状态齐全:默认、悬停、激活、可见焦点、禁用
- 筛选器 / 标签页 / 模态框状态保存在 URL 中
- 触控目标 ≥ 44px,所有功能都不依赖悬停
第 7 步:无障碍访问
运行自动化扫描,然后通过键盘逐项检查。详见 building-accessible-interfaces。
npx @axe-core/cli http://localhost:5173 --exit
- axe 违规项为零,或以书面形式说明每项遗留违规的合理性
- 正文对比度为 4.5:1,大号文本为 3:1——浅色和深色模式下均须满足
- 所有位置的焦点都清晰可见;
outline: none绝不会在没有替代方案的情况下出现 - Tab 键顺序与视觉顺序一致
- 模态框打开时将焦点移入,关闭时将焦点移回原处
- 每张图片都有
alt(装饰性图片使用空值) - 每个纯图标按钮都有可访问名称
- 只有一个
<h1>;标题级别没有跳级 - 存在
<main>、<nav>、<header>地标 - 状态不会仅通过颜色传达
- 异步更新有实时区域,且实时区域先于其内容存在
第 8 步:动效与性能
- 存在
prefers-reduced-motion代码块 - 只对
transform/opacity/filter添加动画,不对width/height/top/left添加动画 - 不使用
transition: all - 用户触发的动效持续时间为 80-450ms
- 进入动画使用缓出;退出动画使用缓入且速度更快
- 操作耗时低于 100ms 时不显示加载旋转图标
- 控制台错误为零
- 字体设置了
font-display: swap,并使用度量匹配的回退字体 - 加载时没有布局偏移(查看截图序列,或检查 CLS)
报告格式
按严重程度排序问题。每项问题都要注明位置、原因和修复方法。
## First Impression
[The 5 answers from Step 2 — the naive read, verbatim]
## Evidence
Rendered at 1440×900 and 390×844. 34 distinct font-sizes, 6 border-radii,
9 box-shadows. 2 console errors. 1 horizontal overflow.
## Critical — breaks the interface for some users
**Focus indicator removed globally**
`src/styles/base.css:12` — `*:focus { outline: none }` with no replacement.
Keyboard users cannot tell where they are; WCAG 2.4.7 failure.
Fix: delete it, add `:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }`.
## Important — visibly degrades quality
**Spacing scale not enforced**
17 distinct padding values including `14px`, `18px`, `22px` (`Card.tsx:8`,
`Panel.tsx:22`, `Modal.tsx:41`). Tokens exist in `:root` but are unused, so
nothing aligns to a common rhythm.
Fix: replace every raw px with the nearest `--space-*` token.
## Minor — polish
**Headings orphan their last word**
`h2` in `Hero.tsx:14` wraps "started" alone onto line 2 at 1440px.
Fix: add `text-wrap: balance`.
## Strengths
[Specific, not flattery. "The type pairing carries the direction" — not "looks good".]
## Verdict
Ship / Ship with the Critical items fixed / Needs rework — plus one sentence of reasoning.
严重程度
| 严重程度 | 定义 |
|---|---|
| 严重 | 部分用户无法使用,或导致数据丢失。键盘陷阱、焦点被移除、正文文本对比度不合格、出错时表单内容被清空、移动设备上出现水平溢出。 |
| 重要 | 明显降低质量或阻碍实际任务。不一致的系统值、缺失的状态、难以阅读的行长、缺少错误恢复机制。 |
| 轻微 | 润色问题。孤行、时长略有偏差、阴影可以再收紧一些。 |
不要凑数。五个真实问题胜过二十个混杂着键盘陷阱和 2px 对齐小问题的发现——凑数会掩盖真正的陷阱。
常见错误
审查代码,而不是界面。 审查要找出的缺陷,是只有在渲染后才能看到的那些。
指出“感觉不对”的问题。 如果说不出原因,就继续找。每个质量问题都有具体原因。
只看桌面端。 大多数缺陷会在 390px 宽度下出现。始终检查两种宽度。
重新设计,而不是审查。 “把它重做成仪表板”不算发现。除非方向本身有问题,否则应修复现有设计——如果确实有问题,就明确指出,并作为一个顶层发现提出。
夸大严重程度。 把所有问题都称为严重,就等于没有严重问题。只有真正无法正常使用时才标为严重。
只列出违规之处,不给出修复方案。 “对比度不合格”只是半个发现。“--ink-3 #8b857c 在 --base #f4f1ea 上的对比度为 2.9:1;将其加深为 #6b6459,即可达到 4.5:1”才是完整的发现。
跳过第一印象。 经过三轮深入检查后,你就无法再还原初次浏览时的感受,而大多数用户只能获得这一次体验。