# Verificador de contraste de cores (WCAG)

> Este verificador calcula a razão de contraste entre a cor do texto e a do fundo, de 1:1 a 21:1, e diz se ela passa nos níveis AA e AAA da WCAG 2.2, para texto normal, texto grande e elementos gráficos. Quando a combinação não passa, ele sugere uma versão da cor do texto, no mesmo tom, que alcança o AA ou o AAA.

- Endereço oficial: https://pradev.com.br/verificador-de-contraste
- Categoria: Front-end e design
- Tipo: Utilitário
- Atualizado em: 2026-10-01
- Autor: Leonardo Gaertner (https://pradev.com.br/sobre)
- Preço: grátis, sem cadastro. O processamento acontece no navegador de quem usa.

## Como usar

1. Digite ou escolha a cor do texto e a cor do fundo.
2. Veja a razão de contraste, a prévia e quais níveis a combinação alcança.
3. Se não passar, clique em uma das sugestões para aplicar a cor ajustada.

## Como funciona

A razão de contraste compara a luminância relativa das duas cores: (L1 + 0,05) ÷ (L2 + 0,05), em que L1 é a da cor mais clara. A luminância considera que o olho é mais sensível ao verde que ao vermelho e ao azul: L = 0,2126 R + 0,7152 G + 0,0722 B, com cada canal convertido para luz linear antes.

A WCAG pede no mínimo 4,5:1 para texto normal e 3:1 para texto grande (a partir de 24px, ou 18,66px em negrito) no nível AA, e 7:1 e 4,5:1 no AAA. Ícones, bordas de campos e outros elementos gráficos precisam de 3:1. O limite é exato: 4,49:1 não passa no AA, por isso a ferramenta mostra a razão sem arredondar para cima.

### Exemplo

```text
Texto #777777 sobre fundo #ffffff: 4,47:1
Passa no AA para texto grande, não passa para texto normal
Sugestão para o AA: um cinza um pouco mais escuro
```

## Em código

Para calcular o contraste da WCAG em código, converta cada canal para luz linear, calcule a luminância das duas cores e divida a maior pela menor, somando 0,05 em cada uma.

```javascript
// Razão de contraste da WCAG 2 entre duas cores em HEX ("#777777" e "#ffffff")
function luminancia(hex) {
  const n = parseInt(hex.replace('#', ''), 16);
  const [r, g, b] = [(n >> 16) & 255, (n >> 8) & 255, n & 255].map((v) => {
    const c = v / 255;
    return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4; // canal em luz linear
  });
  return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}

function contraste(cor1, cor2) {
  const [clara, escura] = [luminancia(cor1), luminancia(cor2)].sort((a, b) => b - a);
  return (clara + 0.05) / (escura + 0.05);
}

const r = contraste('#777777', '#ffffff');
console.log(r.toFixed(2), r >= 4.5 ? 'passa no AA' : 'não passa no AA'); // 4.48 não passa no AA (a razão exata é 4,478...)
```

_JavaScript_

```python
def luminancia(cor: str) -> float:
    """Luminância relativa da WCAG 2 de uma cor em HEX de 6 dígitos."""
    h = cor.lstrip("#")
    canais = []
    for i in (0, 2, 4):
        c = int(h[i : i + 2], 16) / 255
        canais.append(c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4)
    r, g, b = canais
    return 0.2126 * r + 0.7152 * g + 0.0722 * b


def contraste(cor1: str, cor2: str) -> float:
    clara, escura = sorted((luminancia(cor1), luminancia(cor2)), reverse=True)
    return (clara + 0.05) / (escura + 0.05)


r = contraste("#777777", "#ffffff")
print(f"{r:.2f}", "passa no AA" if r >= 4.5 else "não passa no AA")  # 4.48 não passa no AA (a razão exata é 4,478...)
```

_Python_

```php
<?php
// Luminância relativa da WCAG 2 de uma cor em HEX de 6 dígitos
function luminancia(string $cor): float
{
    [$r, $g, $b] = array_map(function (string $par): float {
        $c = hexdec($par) / 255;
        return $c <= 0.04045 ? $c / 12.92 : (($c + 0.055) / 1.055) ** 2.4;
    }, str_split(ltrim($cor, '#'), 2));
    return 0.2126 * $r + 0.7152 * $g + 0.0722 * $b;
}

function contraste(string $cor1, string $cor2): float
{
    $l = [luminancia($cor1), luminancia($cor2)];
    return (max($l) + 0.05) / (min($l) + 0.05);
}

$r = contraste('#777777', '#ffffff');
printf("%.2f %s\n", $r, $r >= 4.5 ? 'passa no AA' : 'não passa no AA'); // 4.48 não passa no AA (a razão exata é 4,478...)
```

_PHP_

## Perguntas frequentes

### O que é texto grande para a WCAG?

Texto de pelo menos 18 pontos (24px) ou de 14 pontos (18,66px) em negrito. Abaixo disso, vale o limite de texto normal: 4,5:1 no AA.

### Logotipos e textos decorativos precisam de contraste?

Não. A WCAG isenta logotipos, textos que fazem parte de uma imagem sem função e elementos desabilitados. Textos em botões, links e campos precisam.

### Como calcular o contraste em código?

Converta cada canal para luz linear, calcule a luminância das duas cores e aplique a razão. A seção Em código, nesta página, mostra a função em JavaScript, Python e PHP, com o mesmo cálculo desta ferramenta. Na hora de exibir, não arredonde para cima: 4,478 aparece como 4,48 com arredondamento comum, mas não chega a 4,5.

### E o APCA, da WCAG 3?

O APCA é um método mais novo, que leva em conta o tamanho e o peso da fonte, e está em discussão para a WCAG 3, que ainda não é norma. As leis e auditorias de acessibilidade, inclusive no Brasil, seguem a WCAG 2, que é o que esta ferramenta calcula.

## Fontes

- [W3C: WCAG 2.2, critério 1.4.3 (contraste mínimo)](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html)
- [W3C: definição de luminância relativa e razão de contraste](https://www.w3.org/TR/WCAG22/#dfn-relative-luminance)

## Guias

- [Contraste de cores e acessibilidade: o que a WCAG exige](https://pradev.com.br/guias/contraste-de-cores-wcag-acessibilidade): O que a WCAG exige de contraste entre texto e fundo (4,5:1 no AA), como a razão é calculada e como corrigir cores que não passam, com código.
- [OKLCH no CSS: cores e paletas que fazem sentido](https://pradev.com.br/guias/oklch-no-css-cores-e-paletas): O que é OKLCH, por que ele gera paletas mais equilibradas que HSL e como usar oklch() no CSS, com a conversão de HEX em JavaScript e Python.

## Ferramentas relacionadas

- [Conversor de Cores HEX RGB HSL](https://pradev.com.br/conversor-de-cores): Converta cores entre HEX, RGB, HSL, OKLCH, HWB, HSV e CMYK, com seletor de cores e os nomes do CSS. Grátis, direto no navegador.
- [Gerador de Paleta a partir de HEX](https://pradev.com.br/gerador-de-paleta-a-partir-de-hex): Gere uma escala de tons de 50 a 950 e combinações (complementar, análogas, tríade) a partir de uma cor. Exporta para CSS e Tailwind.
- [Tabela de Cores HTML](https://pradev.com.br/tabela-de-cores-html): As 148 cores com nome do HTML e do CSS, com HEX, RGB e nome em português. Busque, ordene por tom ou luz e copie com um clique.
- [Conversor px para rem](https://pradev.com.br/conversor-px-rem): Converta px em rem, em, pt e % e o contrário, com a base de 16px ou outra. Tabela com os tamanhos mais usados. Grátis, no navegador.
- [Gerador de Lorem Ipsum](https://pradev.com.br/gerador-de-lorem-ipsum): Gere texto Lorem Ipsum por parágrafos, frases ou palavras, com ou sem tags <p>, para preencher layouts e protótipos. Grátis e sem cadastro.
- [Qual é a Tecla](https://pradev.com.br/qual-e-a-tecla): Aperte uma tecla e veja event.key, event.code, keyCode e os modificadores do JavaScript. Útil para atalhos de teclado e jogos.
