name: ui-testing description: 视觉测试 - 捕捉不可见按钮、破损布局、对比度问题
UI验证技能
加载方式:ui-web.md 或 ui-mobile.md
目的
快速验证生成的UI是否符合无障碍标准。在创建任何新UI组件后运行这些检查。
飞行前检查清单
在发布任何UI之前:
## 可见性检查
- [ ] 所有按钮都有可见的背景或边框
- [ ] 没有文字与其背景颜色相同
- [ ] 所有文字满足4.5:1对比度比率
- [ ] 幽灵/文字按钮有可见边框
## 触摸/点击目标
- [ ] 所有按钮最小高度为44像素
- [ ] 图标按钮最小尺寸为44x44像素
- [ ] 可点击元素之间有足够间距
## 状态
- [ ] 悬停状态可见(网页)
- [ ] 按压状态可见(移动端)
- [ ] 键盘导航时有焦点环
- [ ] 禁用状态视觉上可区分(不透明度0.5)
- [ ] 加载状态显示指示器
## 深色模式(如适用)
- [ ] 文字在深色背景上可读
- [ ] 边框在深色模式下可见
- [ ] 深色背景上不使用gray-400文字
## 响应式(网页)
- [ ] 在移动端(320像素)无水平滚动
- [ ] 在所有断点下内容可读
- [ ] 移动端触摸目标足够大
快速对比度检查
使用浏览器开发者工具
1. 右键点击元素 → 检查
2. 在样式面板中,点击颜色值
3. 查找对比度比率显示
4. 必须显示 ✓ 表示符合AA标准(文字需4.5:1)
在线工具
Tailwind安全组合
浅色模式(白色背景):
✓ text-gray-900 (#111827) = 16:1
✓ text-gray-800 (#1F2937) = 12:1
✓ text-gray-700 (#374151) = 9:1
✓ text-gray-600 (#4B5563) = 6:1
✗ text-gray-500 (#6B7280) = 4.6:1(勉强)
✗ text-gray-400 (#9CA3AF) = 2.6:1(失败)
深色模式(gray-900背景):
✓ text-white (#FFFFFF) = 16:1
✓ text-gray-100 (#F3F4F6) = 13:1
✓ text-gray-200 (#E5E7EB) = 11:1
✓ text-gray-300 (#D1D5DB) = 8:1
✗ text-gray-400 (#9CA3AF) = 5:1(勉强)
✗ text-gray-500 (#6B7280) = 3:1(失败)
常见修复方法
不可见按钮
// 问题:没有可见边界
<button className="text-gray-500">点击</button>
// 修复:添加背景或边框
<button className="bg-gray-100 text-gray-900 px-4 py-3 rounded-lg">
点击
</button>
// 或
<button className="border border-gray-300 text-gray-700 px-4 py-3 rounded-lg">
点击
</button>
低对比度文字
// 问题:浅灰色在白色上
<p className="text-gray-400">次要文字</p>
// 修复:使用更深的灰色
<p className="text-gray-600">次要文字</p>
缺少焦点状态
// 问题:焦点被移除且无替代
<button className="outline-none">提交</button>
// 修复:添加可见焦点环
<button className="outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2">
提交
</button>
触摸目标过小
// 问题:对于手指来说太小
<button className="p-1 text-sm">×</button>
// 修复:最小44像素
<button className="w-11 h-11 flex items-center justify-center">×</button>
深色模式损坏
// 问题:两种模式使用相同颜色
<p className="text-gray-400">文字</p>
// 修复:为深色模式调整
<p className="text-gray-600 dark:text-gray-300">文字</p>
自动化检查(可选)
ESLint插件
npm install -D eslint-plugin-jsx-a11y
// .eslintrc
{
"extends": ["plugin:jsx-a11y/recommended"]
}
Playwright快速测试
// e2e/accessibility.spec.ts
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test('无障碍违规检查', async ({ page }) => {
await page.goto('/');
const results = await new AxeBuilder({ page }).analyze();
expect(results.violations).toEqual([]);
});
何时使用完整测试
在以下情况添加全面的视觉测试(Playwright截图、Storybook):
- 构建组件库时
- 多名开发人员参与UI开发时
- UI频繁变更时
- 需要强制执行设计系统时
对于个人项目或最小可行产品,上述检查清单已足够。