Loading...
Loading...
Compare original and translation side by side
website/design-catalog/website/design-catalog/| Element Type | Level AA | Level AAA |
|---|---|---|
| Normal text (<18px or <14px bold) | 4.5:1 | 7:1 |
| Large text (≥18px or ≥14px bold) | 3:1 | 4.5:1 |
| UI components & graphics | 3:1 | N/A |
| Focus indicators | 3:1 | N/A |
| 元素类型 | AA级别 | AAA级别 |
|---|---|---|
| 普通文本(<18px 或 <14px 粗体) | 4.5:1 | 7:1 |
| 大文本(≥18px 或 ≥14px 粗体) | 3:1 | 4.5:1 |
| UI组件与图形 | 3:1 | N/A |
| 焦点指示器 | 3:1 | N/A |
// WCAG 2.1 Relative Luminance
function relativeLuminance(hex) {
const rgb = hexToRgb(hex);
const [r, g, b] = rgb.map(c => {
const srgb = c / 255;
return srgb <= 0.03928
? srgb / 12.92
: Math.pow((srgb + 0.055) / 1.055, 2.4);
});
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
// Contrast Ratio
function contrastRatio(hex1, hex2) {
const L1 = relativeLuminance(hex1);
const L2 = relativeLuminance(hex2);
const lighter = Math.max(L1, L2);
const darker = Math.min(L1, L2);
return (lighter + 0.05) / (darker + 0.05);
}// WCAG 2.1相对亮度计算
function relativeLuminance(hex) {
const rgb = hexToRgb(hex);
const [r, g, b] = rgb.map(c => {
const srgb = c / 255;
return srgb <= 0.03928
? srgb / 12.92
: Math.pow((srgb + 0.055) / 1.055, 2.4);
});
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
// 对比度比值计算
function contrastRatio(hex1, hex2) {
const L1 = relativeLuminance(hex1);
const L2 = relativeLuminance(hex2);
const lighter = Math.max(L1, L2);
const darker = Math.min(L1, L2);
return (lighter + 0.05) / (darker + 0.05);
}┌─────────────────────────────────────────────────────┐
│ CONTRAST AUDIT │
├─────────────────────────────────────────────────────┤
│ Foreground: #1a1a1a (Deep Black) │
│ Background: #ffffff (White) │
│ Contrast Ratio: [CALCULATED VALUE]:1 │
│ │
│ ✅/❌ Normal Text AA (4.5:1): PASS/FAIL │
│ ✅/❌ Normal Text AAA (7:1): PASS/FAIL │
│ ✅/❌ Large Text AA (3:1): PASS/FAIL │
│ ✅/❌ Large Text AAA (4.5:1): PASS/FAIL │
│ ✅/❌ UI Components (3:1): PASS/FAIL │
└─────────────────────────────────────────────────────┘❌ FAILS AA - Contrast ratio: [X.X]:1
FIX OPTIONS:
1. Darken foreground: #old → #new (ratio: [CALCULATED]:1)
2. Lighten background: #old → #new (ratio: [CALCULATED]:1)
3. Use alternative: #hex on #hex (ratio: [CALCULATED]:1)┌─────────────────────────────────────────────────────┐
│ 对比度审核 │
├─────────────────────────────────────────────────────┤
│ 前景色:#1a1a1a(深黑) │
│ 背景色:#ffffff(白色) │
│ 对比度比值:[计算值]:1 │
│ │
│ ✅/❌ 普通文本AA级(4.5:1):通过/不通过 │
│ ✅/❌ 普通文本AAA级(7:1):通过/不通过 │
│ ✅/❌ 大文本AA级(3:1):通过/不通过 │
│ ✅/❌ 大文本AAA级(4.5:1):通过/不通过 │
│ ✅/❌ UI组件(3:1):通过/不通过 │
└─────────────────────────────────────────────────────┘❌ 未通过AA级 - 对比度比值:[X.X]:1
修复选项:
1. 加深前景色:#旧值 → #新值(比值:[计算值]:1)
2. 提亮背景色:#旧值 → #新值(比值:[计算值]:1)
3. 使用替代组合:#颜色1 搭配 #颜色2(比值:[计算值]:1)role="button"<button>aria-disabled="true"disabledaria-busy="true"<label for="">aria-labelaria-invalid="true"aria-describedbyaria-required="true"required<nav>role="navigation"aria-current="page"role="button"<button>aria-disabled="true"disabledaria-busy="true"<label for="">aria-labelaria-invalid="true"aria-describedbyaria-required="true"required<nav>role="navigation"aria-current="page"undefinedundefinedundefinedundefined/* Before: fails AA */
color: #9ca3af;
/* After: passes AA (calculate to verify) */
color: #6b7280;/* 修复前:未通过AA级 */
color: #9ca3af;
/* 修复后:通过AA级(需计算验证) */
color: #6b7280;/* Universal focus style */
:focus-visible {
outline: 2px solid #000000;
outline-offset: 2px;
}
/* Or for brand color (verify 3:1 contrast) */
:focus-visible {
outline: 3px solid #2563eb;
outline-offset: 2px;
}/* 通用焦点样式 */
:focus-visible {
outline: 2px solid #000000;
outline-offset: 2px;
}
/* 或使用品牌色(需验证3:1对比度) */
:focus-visible {
outline: 3px solid #2563eb;
outline-offset: 2px;
}/* Before: too small */
.icon-btn {
width: 32px;
height: 32px;
}
/* After: meets 44px minimum */
.icon-btn {
width: 44px;
height: 44px;
/* Or use padding */
padding: 12px;
}/* 修复前:尺寸过小 */
.icon-btn {
width: 32px;
height: 32px;
}
/* 修复后:符合44px最小要求 */
.icon-btn {
width: 44px;
height: 44px;
/* 或使用内边距扩展 */
padding: 12px;
}<!-- Before: no accessible name -->
<button><svg>...</svg></button>
<!-- After: accessible -->
<button aria-label="Close dialog">
<svg aria-hidden="true">...</svg>
</button><!-- 修复前:无无障碍名称 -->
<button><svg>...</svg></button>
<!-- 修复后:具备无障碍属性 -->
<button aria-label="关闭对话框">
<svg aria-hidden="true">...</svg>
</button>