Acessibilidade cromática: contraste, daltonismo e WCAG
Utilitários陈雨萱
Acessibilidade cromática: não é apenas "bonito"
Cerca de 8% dos homens e 0,5% das mulheres no mundo têm deficiência de visão cromática — 1 em cada 12 usuários não consegue distinguir normalmente certas cores.
| Tipo de deficiência cromática | Prevalência | Cores difíceis de distinguir |
|---|---|---|
| Protanopia (cegueira ao vermelho) | 1% | Vermelho-verde |
| Deuteranopia (cegueira ao verde) | 5% | Vermelho-verde |
| Tritanopia (cegueira ao azul) | 0,003% | Azul-amarelo |
| Acromatopsia (cegueira total ao cor) | Extremamente rara | Todas |
I. Padrões de contraste WCAG
Níveis de conformidade
| Nível | Texto normal | Texto grande | Componentes UI |
|---|---|---|---|
| AA | ≥ 4,5:1 | ≥ 3:1 | ≥ 3:1 |
| AAA | ≥ 7:1 | ≥ 4,5:1 | — |
Definição de texto grande: ≥ 18pt (24px) ou ≥ 14pt negrito (18,66px bold).
Cálculo do contraste
Contraste = (L1 + 0,05) / (L2 + 0,05)
L1 = Luminância relativa da cor mais clara
L2 = Luminância relativa da cor mais escura
Luminância relativa L:
Para sRGB onde sRGB ≤ 0,03928: L = sRGB / 12,92
Para sRGB onde sRGB > 0,03928: L = ((sRGB + 0,055) / 1,055)^2,4
sRGB = R/255, G/255, B/255 (calculado por canal)
Contraste de combinações comuns
| Primeiro plano | Fundo | Contraste | AA texto normal | AA texto grande |
|---|---|---|---|---|
#000000 |
#FFFFFF |
21:1 | ✅ | ✅ |
#333333 |
#FFFFFF |
12,6:1 | ✅ | ✅ |
#666666 |
#FFFFFF |
5,7:1 | ✅ | ✅ |
#767676 |
#FFFFFF |
4,5:1 | ✅ (exato) | ✅ |
#999999 |
#FFFFFF |
2,8:1 | ❌ | ❌ |
#FF0000 |
#FFFFFF |
3,99:1 | ❌ | ✅ |
#0000FF |
#FFFFFF |
8,59:1 | ✅ | ✅ |
II. Verificando o contraste com ToolsKu
Passos de operação
- Abra a ferramenta de contraste de cor
- Insira a cor do primeiro plano e do fundo (suporta HEX, RGB, HSL)
- Revise os resultados:
- Proporção de contraste
- Status de conformidade WCAG AA / AAA
- Avaliação separada para texto normal / texto grande
- Ajuste as cores até que estejam em conformidade
III. Simulação de daltonismo
Simulação com CSS filter
/* Protanopia */
.protanopia { filter: url('#protanopia'); }
/* Deuteranopia */
.deuteranopia { filter: url('#deuteranopia'); }
/* Tritanopia */
.tritanopia { filter: url('#tritanopia'); }
Matriz de filtro SVG
<svg style="display:none">
<!-- Matriz de simulação de protanopia -->
<filter id="protanopia">
<feColorMatrix type="matrix" values="
0.567 0.433 0 0 0
0.558 0.442 0 0 0
0 0.242 0.758 0 0
0 0 0 1 0
"/>
</filter>
<!-- Matriz de simulação de deuteranopia -->
<filter id="deuteranopia">
<feColorMatrix type="matrix" values="
0.625 0.375 0 0 0
0.7 0.3 0 0 0
0 0.3 0.7 0 0
0 0 0 1 0
"/>
</filter>
</svg>
IV. Estratégias de adaptação para daltonismo
Estratégia 1: Não depender apenas da cor para transmitir informações
<!-- Incorreto: distinguir estados apenas com cor -->
<span class="status-error" style="color: red">Falhou</span>
<span class="status-success" style="color: green">Sucesso</span>
<!-- Correto: cor + ícone -->
<span class="status-error" style="color: red">
<svg>✕</svg> Falhou
</span>
<span class="status-success" style="color: green">
<svg>✓</svg> Sucesso
</span>
Estratégia 2: Usar combinações de cores amigáveis para daltônicos
| Combinação a evitar | Combinação alternativa |
|---|---|
| Vermelho + Verde | Vermelho + Azul, ou Laranja + Azul |
| Vermelho claro + Verde claro | Vermelho escuro + Verde claro |
| Verde sucesso + Vermelho erro | Azul informação + Laranja aviso |
Paleta amigável para daltônicos de Wong
#000000 Preto
#E69F00 Laranja
#56B4E9 Azul celeste
#009E73 Verde azulado
#F0E442 Amarelo
#0072B2 Azul
#D55E00 Vermelho bermelho
#CC79A7 Rosa púrpura
Esta paleta é distinguível sob todos os tipos de deficiência de visão cromática.
Estratégia 3: Usar texturas/padrões em gráficos
/* Diferentes séries de dados usam diferentes texturas */
.series-a { background-image: url('stripes.svg'); }
.series-b { background-image: url('dots.svg'); }
.series-c { background-image: url('crosshatch.svg'); }
V. Acessibilidade no modo escuro
Armadilhas de contraste no modo escuro
| Armadilha | Descrição | Solução |
|---|---|---|
| Fundo preto puro com texto branco puro | Contraste 21:1, mas causa fadiga visual | Usar fundo cinza escuro (#1a1a2e) |
| Reduzir saturação | Alta saturação no modo escuro é ofuscante | Reduzir saturação adequadamente |
| Sombras não visíveis | Sombras desaparecem em fundo escuro | Usar bordas ou diferença de luminância |
| Contraste insuficiente de imagens | Detalhes de imagens se perdem no modo escuro | Ajustar com CSS filter |
Sugestões de cores para modo escuro
:root {
/* Modo claro */
--bg: #ffffff;
--fg: #1a1a2e;
--muted: #6b7280;
--accent: #3b82f6;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #1a1a2e;
--fg: #e0e0e0;
--muted: #9ca3af;
--accent: #60a5fa; /* Azul mais claro, mantém contraste */
}
}
VI. Verificação de acessibilidade em nível de componente
Mensagens de erro em formulários
<!-- Incorreto: apenas borda vermelha como indicação -->
<input style="border: 1px solid red" />
<!-- Correto: borda + texto + aria -->
<input
style="border: 1px solid red"
aria-invalid="true"
aria-describedby="error-msg"
/>
<span id="error-msg" role="alert" style="color: #dc2626">
Por favor, insira um endereço de e-mail válido
</span>
Contraste entre links e texto circundante
Os links não apenas precisam de contraste suficiente com o fundo, mas também de distinção visual com o texto circundante:
/* Links se distinguem não apenas pela cor, mas também pelo sublinhado */
a {
color: var(--accent);
text-decoration: underline;
text-underline-offset: 2px;
}
VII. Detecção automatizada
Integração com axe-core
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('acessibilidade cromática', async () => {
const { container } = render(<MyComponent />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
Auditoria com Lighthouse
npx lighthouse https://example.com --only-categories=accessibility
Integração CI
- name: Accessibility check
run: npx pa11y https://staging.example.com
VIII. Lista de melhores práticas
- Contraste de texto ≥ 4,5:1 (texto normal nível AA)
- Não depender apenas da cor para transmitir informações de estado
- Usar paleta amigável para daltônicos (como a paleta de Wong)
- Adicionar texturas/padrões a gráficos para distinguir
- Manter contraste no modo escuro, evitar fundo preto puro
- Links têm sublinhado ou outra distinção não cromática
- Mensagens de erro têm texto descritivo, não apenas cor vermelha
- Testes automatizados de acessibilidade integrados ao CI
#无障碍#WCAG#对比度#色盲#色彩设计