# Contraste de cor: texto legível para todos

[Canonical HTML page](https://gradiently.design/pt-pt/guide/color-contrast-accessibility)

O contraste é a diferença entre palavras que as pessoas leem e palavras que saltam. Os números das WCAG em linguagem simples, como os verificar e o que muda quando o fundo é um gradiente.

## The short version

- O contraste de cor é a diferença de luminosidade entre o texto e o fundo, medida como um rácio de 1:1 (sem diferença) a 21:1 (preto sobre branco).
- O nível AA das WCAG 2 pede pelo menos 4,5:1 para texto normal e 3:1 para texto grande, que são cerca de 24 px em peso normal ou 18,66 px a negrito.
- Os ícones, os limites dos campos e outras partes de uma interface que as pessoas precisam de ver também precisam de pelo menos 3:1 em relação ao que as rodeia.
- Sobre branco, `#767676` é o cinzento simples mais claro que passa 4,5:1 para texto corrente, e `#777777` falha por pouco.
- Num gradiente, o contraste muda de ponto para ponto, por isso tens de testar o pior ponto por trás das palavras e não a cor média.

O **contraste de cor** é a diferença de luminosidade entre o texto e a cor que está por trás, e decide se as pessoas conseguem sequer ler as tuas palavras. As Diretrizes de Acessibilidade para o Conteúdo da Web (WCAG) medem-no como um rácio de 1:1, em que as duas cores são idênticas, a 21:1, preto sobre branco. Para o nível AA, o texto normal precisa de pelo menos **4,5:1** e o texto grande de pelo menos **3:1**. Tudo o resto neste guia trata de atingir esses números sem tornar o teu design tímido.

O contraste importa a toda a gente, não só a quem tem visão reduzida. Telemóveis ao sol, projetores fracos, monitores baratos e olhos cansados reduzem a diferença entre cores. Os designs com contraste suficiente são simplesmente mais lidos.

## Os rácios de contraste das WCAG em palavras simples

Três regras das WCAG 2 cobrem quase todas as decisões de design. Vêm dos [critérios de êxito do W3C](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html) e são aquilo a que se referem a maioria das auditorias e regulamentos de acessibilidade.

| O quê | Nível AA | Nível AAA | Notas |
| --- | --- | --- | --- |
| Texto normal | 4,5:1 | 7:1 | Texto corrente, legendas, etiquetas, botões |
| Texto grande | 3:1 | 4,5:1 | Pelo menos 18 pt (cerca de 24 px), ou 14 pt a negrito (cerca de 18,66 px) |
| Ícones e partes da interface | 3:1 | 3:1 | Limites de campos, linhas de gráficos com significado, ícones sem etiqueta |
| Logótipos e decoração | Nenhum | Nenhum | Os logótipos de marca e o texto puramente decorativo estão isentos |

O nível AA é o objetivo habitual. O AAA é mais exigente e vale a pena procurá-lo em leituras longas.

Dois pormenores apanham as pessoas desprevenidas. Primeiro, “grande” refere-se ao tamanho apresentado, por isso um título de 24 px num telemóvel que o reduz pode deixar de contar como grande. Segundo, um botão desativado está isento, mas um texto de exemplo cinzento-claro que as pessoas precisam de compreender não está.

## Como se calcula o rácio de contraste

O rácio compara a luminância relativa das duas cores: quanta luz cada uma emite, ponderada da forma como o olho vê. O verde contribui mais, o vermelho menos e o azul muito pouco, e é por isso que um azul saturado pode ser surpreendentemente escuro e um amarelo surpreendentemente claro. A fórmula é `(L1 + 0.05) / (L2 + 0.05)`, em que L1 é a cor mais clara.

```js
// WCAG 2 contrast ratio between two hex colours
const channel = (c) => {
  c /= 255
  return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4
}
const luminance = (hex) => {
  const [r, g, b] = [1, 3, 5].map((i) => channel(parseInt(hex.slice(i, i + 2), 16)))
  return 0.2126 * r + 0.7152 * g + 0.0722 * b
}
const contrast = (a, b) => {
  const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x)
  return (hi + 0.05) / (lo + 0.05)
}

contrast('#767676', '#ffffff') // 4.54, passes for body text
contrast('#777777', '#ffffff') // 4.48, fails
```

Todo o cálculo cabe em uma dúzia de linhas. Útil para verificar uma paleta de marca em série.

Não precisas de o calcular à mão. O [verificador de contraste da WebAIM](https://webaim.org/resources/contrastchecker/) recebe dois códigos hexadecimais e diz-te que níveis passam, e o seletor de cor das ferramentas de programador do Chrome mostra o rácio de qualquer texto que inspecionares.

## Pares de cores que passam e que falham

As cores da marca ficam muitas vezes num meio-termo incómodo, demasiado escuras para texto escuro e demasiado claras para texto branco. Os verdes, laranjas, rosas e azuis-claros médios são os suspeitos habituais. Estas são combinações comuns, com os seus rácios reais.

| Texto sobre fundo | Rácio | Texto normal | Texto grande |
| --- | --- | --- | --- |
| Branco sobre violeta `#7c3aed` | 5,7:1 | Passa | Passa |
| Branco sobre violeta-claro `#8b5cf6` | 4,2:1 | Falha | Passa |
| Branco sobre azul `#2563eb` | 5,2:1 | Passa | Passa |
| Branco sobre azul-céu `#3b82f6` | 3,7:1 | Falha | Passa |
| Branco sobre verde `#10b981` | 2,5:1 | Falha | Falha |
| Quase preto `#0b0b10` sobre verde `#10b981` | 7,7:1 | Passa | Passa |
| Branco sobre âmbar `#f59e0b` | 2,2:1 | Falha | Falha |
| Cinzento `#999999` sobre branco | 2,9:1 | Falha | Falha |
| Cinzento `#6b7280` sobre branco | 4,8:1 | Passa | Passa |

Uma pequena mudança pode decidir: dois azuis quase iguais ficam em lados opostos de 4,5:1.

> **Inverte o texto, não a marca** Quando o branco falha sobre uma cor de marca viva, experimenta texto quase preto. O verde, o âmbar e o coral costumam passar à vontade com tipografia escura, e a cor fica exatamente como está. O guia sobre [escolher as cores da marca](https://gradiently.design/pt-pt/guide/how-to-choose-brand-colors) trata de incorporar isto numa paleta desde o início.

## Porque é que os gradientes tornam o contraste mais difícil

Um fundo liso tem um só rácio de contraste. Um gradiente tem um diferente em cada ponto. O texto branco que passa facilmente sobre a ponta escura de uma mistura pode falhar por completo na ponta clara, e um título que se estende por todo o gradiente passa e falha na mesma linha.

Meia-noite, violeta e rosa: `linear-gradient(90deg, #1f0b3a 0%, #7c3aed 55%, #f472b6 100%)`

O texto branco obtém 18:1 à esquerda, 5,7:1 sobre o violeta e 2,7:1 na ponta rosa. Um só gradiente, três veredictos.

A regra é simples: testa o ponto mais claro por trás de texto claro, ou o ponto mais escuro por trás de texto escuro. Se o pior ponto passar, a linha toda passa. As cores médias e as amostras do conta-gotas a meio vão induzir-te em erro.

## Como corrigir o contraste num gradiente

1. **Leva as palavras para a ponta calma** Coloca o texto sobre a parte mais escura ou mais clara do gradiente e deixa a transição luminosa acontecer longe dele.
2. **Estreita a gama por trás do texto** Mantém a parte do gradiente que fica por trás das palavras dentro de uma pequena gama de luminosidade. O resto da tela pode ser tão ousado quanto quiseres.
3. **Acrescenta uma película suave** Um esbatido suave, escuro ou claro, por trás do texto, como um gradiente de transparente a preto a 30%, aumenta o contraste sem uma caixa visível.
4. **Vai maior e mais forte** O texto grande só precisa de 3:1. Um peso mais forte e um tamanho maior podem transformar uma linha que falha numa que passa.
5. **Testa num telemóvel real** Verifica o design com o brilho no máximo e com pouco brilho, ao ar livre se puderes. Os rácios são o mínimo, não o objetivo.

```css
.card {
  background: linear-gradient(90deg, #1f0b3a 0%, #7c3aed 55%, #f472b6 100%);
  color: #ffffff;
}
/* A soft scrim keeps white text above 4.5:1 across the pink end */
.card .text {
  background: linear-gradient(90deg, transparent 0%, rgb(31 11 58 / 0.55) 60%);
  padding: 1rem 1.25rem;
}
```

A película escurece só onde o gradiente clareia, por isso o lado esquerdo fica intacto.

Uma publicação vertical em que o título Abrimos as portas às sete atravessa uma zona luminosa do gradiente e fica difícil de ler

As palavras passam direitas pela zona mais luminosa do campo e o contraste cai.

A mesma publicação vertical com uma zona mais escura e calma do gradiente por trás do título, para que se leia com clareza

O mesmo design com a região calma e escura movida para trás das palavras.

É esta a ideia por trás da legibilidade da Gradiently: um Mark sabe onde estão as tuas palavras, move a sua região mais calma e de melhor contraste para trás delas e escolhe tinta clara ou escura por linha a partir da sua própria paleta. Para mais técnicas que funcionam em qualquer lado, lê [texto sobre um gradiente](https://gradiently.design/pt-pt/guide/text-on-gradient) e [texto legível sobre fotografias](https://gradiently.design/pt-pt/guide/text-over-image). Para interfaces escuras em particular, vê [desenhar para o modo escuro](https://gradiently.design/pt-pt/guide/dark-mode-design).

## FAQ

### Qual é um bom rácio de contraste de cor?

Pelo menos 4,5:1 para texto normal e 3:1 para texto grande cumpre o nível AA das WCAG. Para leitura longa, 7:1 (nível AAA) é mais confortável.

### O que conta como texto grande nas WCAG?

Texto de pelo menos 18 pontos, cerca de 24 px, ou pelo menos 14 pontos a negrito, cerca de 18,66 px. O texto grande só precisa de 3:1 no nível AA.

### Qual é o cinzento mais claro que posso usar sobre branco?

`#767676` é o cinzento simples mais claro que atinge 4,5:1 sobre branco. `#777777` mede 4,48:1 e falha para texto corrente.

### Os logótipos têm de cumprir os requisitos de contraste?

Não. As WCAG isentam o texto que faz parte de um logótipo ou de um nome de marca, e o texto puramente decorativo. Tudo o que as pessoas precisam de ler ou usar continua a contar.

### Como verifico o contraste num fundo em gradiente?

Mede a cor do texto contra o ponto mais claro por trás de texto claro, ou contra o ponto mais escuro por trás de texto escuro. Se esse pior ponto passar, a linha toda passa.
