Programação Por Equipe DevBras

Capa do artigo: Texto cinza claro que ninguém lê: como medir e corrigir o contraste

Texto cinza claro que ninguém lê: como medir e corrigir o contraste

Calcule o contraste do seu cinza contra o fundo real, entenda os mínimos da WCAG para texto normal e grande e escolha tons que passam sem perder o visual.

O redesign do blog ficou "leve": texto em #999 sobre branco, metadados em #bbb. No monitor calibrado da agência, ficou bonito. No celular, ao meio-dia, com o brilho no automático, a pessoa precisa inclinar a tela para ler a frase. A resposta curta: texto normal precisa de contraste de pelo menos 4,5:1 com o fundo; texto grande, de 3:1, segundo o critério 1.4.3 da WCAG. O #999 sobre branco dá 2,85:1 e reprova. O cinza mais claro que passa em texto normal sobre branco puro é perto de #767676, e um tom como #666 dá folga. Meça contra o fundo real da página, não contra o branco do protótipo.

Cinza não é proibido. Ele só precisa ser escuro o bastante para o que está escrito com ele.

Por que o cinza que parecia ótimo some

O contraste que você enxerga depende da tela, da luz ambiente e dos seus olhos. Monitor de escritório, com brilho alto e luz controlada, é o melhor caso. Celular ao sol, notebook com brilho reduzido para economizar bateria, tela velha com o painel desgastado e pessoas com visão reduzida são o caso comum. A diferença de luminância que sobra nessas condições é bem menor que a do protótipo.

A WCAG resolve isso com uma conta objetiva. Ela calcula a luminância relativa das duas cores, de 0 (preto) a 1 (branco), e faz a razão (L1 + 0,05) / (L2 + 0,05), com a cor mais clara em cima. Preto sobre branco dá 21:1, o máximo. A mesma cor sobre ela mesma dá 1:1. Os mínimos do nível AA, que é o nível mais usado como referência, são:

  • 4,5:1 para texto normal.
  • 3:1 para texto grande, definido como pelo menos 18 pontos, ou 14 pontos em negrito. Em CSS, isso dá cerca de 24 pixels, ou cerca de 18,66 pixels em negrito.

O nível AAA, no critério 1.4.6, pede 7:1 e 4,5:1. Texto de elemento desabilitado, texto puramente decorativo e logotipos ficam fora da exigência.

O cálculo no exemplo do blog

A luminância de um cinza vem do valor de cada canal convertido para uma escala linear. Para o #999, cada canal vale 153 de 255, ou 0,6, que na escala linear vira cerca de 0,318. O branco vale 1. A conta fica:

(1 + 0,05) / (0,318 + 0,05) = 1,05 / 0,368 = 2,85

Reprovado para qualquer tamanho de texto, inclusive o grande. Fazendo a mesma conta com outros tons sobre branco puro:

#999999  2,85:1   reprova
#777777  4,48:1   reprova por pouco
#767676  4,54:1   passa em texto normal
#666666  5,74:1   passa com folga
#595959  7,00:1   chega perto do nível AAA

Agora o detalhe que pegou o blog. O fundo da área de leitura não era branco: era #f5f5f5, para ficar "mais suave". Sobre esse fundo, o mesmo #767676 cai para cerca de 4,17:1 e reprova. O protótipo mostrava os textos sobre branco, e foi lá que alguém conferiu.

A correção ficou assim: texto do artigo em #333, metadados em #5c5c5c, fundo mantido em #f5f5f5. Os dois passam com folga, e o visual continua sem o preto puro que o designer queria evitar.

Transparência também é cor

Texto em rgba(0, 0, 0, 0.4) parece mais "elegante" no código, mas sobre branco ele resulta exatamente em #999: 2,85:1. E sobre um fundo colorido ou uma imagem, o resultado muda a cada ponto. Para medir, calcule a cor que aparece de fato na tela, não a declarada no CSS.

Como auditar e corrigir o contraste

  1. Liste os pares de cor do texto: corpo, metadados, links, legendas, placeholder, botões, rodapé, mensagens de erro.
  2. Para cada par, identifique o fundo real em que ele aparece, inclusive cartões, faixas e imagens.
  3. Meça a razão com o seletor de cor das ferramentas de desenvolvedor do Chrome ou do Edge, que mostra o contraste e indica se passa em AA e AAA, ou com o verificador de contraste da WebAIM.
  4. Rode o Lighthouse ou o axe na página para pegar os casos que você esqueceu.
  5. Escureça o texto, não o fundo, quando o fundo faz parte da identidade visual.
  6. Troque os valores nas variáveis do tema, para a correção valer no site inteiro.
  7. Teste num celular real, com brilho baixo e, se possível, ao ar livre.

As variáveis do tema corrigidas

:root {
  --fundo-leitura: #f5f5f5;
  --texto: #333333;
  --texto-secundario: #5c5c5c;
  --borda-campo: #8a8a8a;
}

body {
  background: var(--fundo-leitura);
  color: var(--texto);
}

.meta {
  color: var(--texto-secundario);
}

A borda dos campos de formulário também entra na conta, por outro critério: a WCAG 2.1 incluiu o 1.4.11, que pede 3:1 para componentes de interface e elementos gráficos necessários para entender o conteúdo. Uma borda de campo quase invisível faz a pessoa não saber onde clicar.

O que o contraste não resolve sozinho

Placeholder costuma vir em cinza claro por padrão, e muita gente o usa como rótulo. Quando a pessoa começa a digitar, ele some, e a informação vai junto. Use um rótulo visível e deixe o placeholder só como exemplo de formato. Mensagens de erro não podem depender só da cor vermelha: acrescente texto ou ícone com significado. E respeite o modo de cores forçadas do sistema, como o alto contraste do Windows: a media query forced-colors: active permite ajustar o que quebrar nele.

Se as cores vieram de um gerador de paletas, o post paleta gerada por ferramenta mostra como conferir antes de aplicar, e cor no CSS: o contraste é o que se lê trata das notações de cor e da escolha de pares.

Erros comuns

  • Medir contra o fundo do protótipo. O fundo real, levemente cinza ou colorido, derruba a razão e o texto reprova em produção.
  • Usar opacidade para clarear o texto. A cor final depende do fundo e costuma ficar mais clara do que parece no código.
  • Tratar metadado como texto grande. Data e autor em 13 pixels são texto normal e precisam de 4,5:1.
  • Placeholder como único rótulo. Ele já vem fraco e ainda some quando a pessoa digita.
  • Erro indicado só pela cor. Quem não distingue vermelho de verde, ou lê ao sol, não percebe que o campo falhou.
  • Corrigir cor por cor no CSS. Sem variáveis de tema, o cinza antigo volta no próximo componente novo.

Checklist

  • Todo texto normal tem pelo menos 4,5:1 contra o fundo onde aparece.
  • Texto grande tem pelo menos 3:1, e o tamanho está de fato acima do limite.
  • Bordas de campo e ícones necessários têm pelo menos 3:1.
  • As cores de texto vêm de variáveis do tema, não de valores soltos.
  • Nenhum texto com informação usa opacidade sobre fundo variável.
  • Formulários têm rótulo visível além do placeholder.
  • A página passa no Lighthouse ou no axe sem alertas de contraste.
  • Alguém leu a página num celular com brilho baixo.

Pegue o tom de cinza do texto secundário do seu site e o fundo exato onde ele aparece, coloque os dois no medidor de contraste: o número passa de 4,5, ou o seu cinza está contando com uma tela boa?

Avalie este artigo

Referência: https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html