Contraste adequado entre texto e fundo é essencial para:
Contraste = (L1 + 0.05) / (L2 + 0.05)
Onde:
/* Texto escuro em fundo claro - 4.5:1+ */
.texto-escuro {
color: #000000; /* Preto */
background: #ffffff; /* Branco */
/* Contraste: 21:1 */
}
/* Texto claro em fundo escuro - 4.5:1+ */
.texto-claro {
color: #ffffff; /* Branco */
background: #1a1a1a; /* Cinza escuro */
/* Contraste: 12.6:1 */
}
/* Texto cinza claro em fundo branco - menos de 4.5:1 */
.texto-ruim {
color: #cccccc; /* Cinza claro */
background: #ffffff; /* Branco */
/* Contraste: 1.6:1 - MUITO BAIXO */
}
<!-- ❌ Ruim - apenas cor indica erro -->
<span style="color: red;">Campo obrigatório</span>
<!-- ✅ Bom - cor + ícone + texto -->
<span style="color: red;">
<span aria-hidden="true">⚠️</span>
<strong>Campo obrigatório</strong>
</span>
<!-- ✅ Bom - múltiplos indicadores -->
<label>
Email
<input
type="email"
aria-invalid="true"
aria-describedby="email-error"
class="input-error">
<span id="email-error" class="error-message">
<span aria-hidden="true">⚠️</span>
Email inválido
</span>
</label>
.input-error {
border: 2px solid #d32f2f; /* Vermelho */
background-color: #ffebee; /* Vermelho claro */
}
.error-message {
color: #d32f2f;
font-weight: bold;
}
/* Link normal */
a {
color: #0066cc; /* Azul com bom contraste */
text-decoration: underline;
}
/* Link visitado */
a:visited {
color: #551a8b; /* Roxo com bom contraste */
}
/* Link com foco */
a:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
button {
background: #0066cc;
color: #ffffff;
border: 2px solid #0066cc;
}
button:hover {
background: #0052a3; /* Mais escuro */
}
button:focus {
outline: 3px solid #ffcc00; /* Amarelo com bom contraste */
outline-offset: 2px;
}
button:active {
background: #003d7a; /* Ainda mais escuro */
}
/* Tema claro (padrão) */
:root {
--bg-color: #ffffff;
--text-color: #000000;
--link-color: #0066cc;
}
/* Tema escuro */
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #1a1a1a;
--text-color: #ffffff;
--link-color: #4da6ff; /* Azul mais claro para contraste */
}
}
body {
background: var(--bg-color);
color: var(--text-color);
}
/* Respeitar preferências de alto contraste */
@media (prefers-contrast: high) {
body {
background: #000000;
color: #ffffff;
}
a {
color: #ffff00; /* Amarelo para máximo contraste */
text-decoration: underline;
}
}
<!-- ✅ Bom - não depende apenas de cor -->
<svg>
<rect fill="#0066cc" aria-label="Q1: 100 vendas">
<title>Q1: 100 vendas</title>
</rect>
<rect fill="#ff6b6b" aria-label="Q2: 150 vendas">
<title>Q2: 150 vendas</title>
</rect>
<!-- Padrões diferentes para cada barra -->
</svg>
<table>
<thead>
<tr>
<th style="background: #333; color: #fff;">Produto</th>
<th style="background: #333; color: #fff;">Vendas</th>
</tr>
</thead>
<tbody>
<tr>
<td>Produto A</td>
<td>100</td>
</tr>
</tbody>
</table>
Use ferramentas para verificar contraste durante o desenvolvimento.
Contraste necessário pode variar dependendo do contexto e tamanho do texto.
Use cor, ícones, texto e padrões para transmitir informação.
Suporte modo escuro e alto contraste quando possível.
Teste com pessoas que têm deficiência visual para feedback real.