- O CSS
contrast-color() faz o navegador escolher texto preto ou branco de acordo com uma cor que muda com frequência, como o fundo de um botão, reduzindo o trabalho de gerenciar pares de cores separadamente
- Ao passar uma cor de referência, como em
color: contrast-color(var(--button-color));, a opção com maior contraste é recalculada conforme a cor de fundo muda
- Atualmente, o Safari Technology Preview usa o algoritmo de contraste do WCAG 2 e escolhe texto preto sobre o fundo
#317CFF, mas para a percepção humana o branco pode parecer mais natural
- Esse recurso não garante acessibilidade automaticamente, e ainda exige validação de design de paleta, tamanho do texto, peso da fonte e itens como
prefers-contrast
- O CSS Working Group está oferecendo o recurso de forma mais restrita, como uma escolha entre preto e branco, até que a discussão sobre o algoritmo de contraste do WCAG 3 seja concluída; ferramentas de seleção de cor mais complexas podem ser expandidas depois
contrast-color() reduz a carga de gerenciar cores
- Ao criar botões com vários fundos em um site ou app web, é preciso combinar texto branco quando o fundo é escuro e texto preto quando ele é claro
- Antes, era necessário definir juntos
--button-color e --button-text-color para gerenciar pares de cores; em projetos grandes ou com várias equipes, é difícil manter essas combinações sempre corretas
- Com
contrast-color(), ao passar uma cor de referência no CSS, o navegador escolhe entre preto e branco a cor com maior contraste
color: contrast-color(purple);
- Em botões, é possível aplicar a variável da cor de fundo junto com
contrast-color()
button {
background-color: var(--button-color);
color: contrast-color(var(--button-color));
}
- Nesse modelo, basta definir uma única cor de fundo, e o navegador decide a cor do texto
Derivar até as cores de estado a partir de uma única variável
- Usando junto a Relative Color Syntax, é possível criar a cor de hover a partir da cor base do botão e também calcular a cor do texto de cada estado com
contrast-color()
:root {
--button-color: purple;
--hover-color: oklch(from var(--button-color) calc(l + .2) c h);
}
button {
background-color: var(--button-color);
color: contrast-color(var(--button-color));
text-box: cap alphabetic; /* vertically centers the text */
}
button:hover {
background-color: var(--hover-color);
color: contrast-color(var(--hover-color));
}
Resultados estranhos gerados por cálculos baseados em WCAG 2
contrast-color() não resolve automaticamente todos os problemas de contraste para acessibilidade
- Algumas cores de fundo podem não produzir contraste suficiente nem com preto nem com branco, então a verificação de designers, desenvolvedores e testers continua necessária
- Na implementação do Safari Technology Preview em maio de 2025, é usado o algoritmo do WCAG 2
- No fundo azul
#317CFF, o WCAG 2 calcula contraste de 5.45:1 para texto preto
- No mesmo fundo, o contraste do texto branco é calculado como 3.84:1
contrast-color() escolhe o preto por ser o número maior
- Para a percepção humana, porém, o branco pode parecer melhor nessa combinação, e o algoritmo de contraste de cores do WCAG 2 já recebe críticas há muito tempo
A discussão sobre algoritmos de contraste segue com APCA e WCAG 3
- O Accessible Perceptual Contrast Algorithm (APCA) é um dos candidatos que podem ser incluídos no WCAG 3
- A APCA Contrast Calculator avalia no fundo
#317CFF o texto preto como Lc 38.7 e o texto branco como Lc -70.9
- No score do APCA, um valor negativo significa que o texto é mais claro que o fundo
- A magnitude do contraste é comparada por 38.7 e 70.9, desconsiderando o sinal
- Nesse resultado, o texto branco tem contraste maior
- O APCA prioriza contraste baseado em percepção, em vez de uma simples proporção matemática, refletindo o fato de que as pessoas não percebem contraste de forma linear dependendo da cor e do brilho
- O padrão CSS ainda exige o uso do algoritmo atual, mas inclui uma observação de que outros algoritmos de contraste podem ser adicionados no futuro
- Ainda segue em discussão qual algoritmo será usado no WCAG 3 e como tratar as licenças dos algoritmos candidatos
Condições que ainda precisam ser verificadas no design real
contrast-color() escolher uma cor melhor não é o mesmo que garantir contraste suficiente
- Especialmente em cores de tom médio, a diferença entre algoritmos pode ser grande
- Para usuários que querem mais contraste, é possível usar junto a media query
prefers-contrast
@media (prefers-contrast: more) {
/* styling with more contrast */
}
- No exemplo, o site de um viveiro usa
#2DAD4E como cor de fundo dos botões da marca
- Pelo APCA, o contraste com texto branco é Lc -60.4
- Se esse valor é suficiente depende do tamanho do texto e do peso da fonte
- O APCA usa uma pontuação única de Lc -108 a 106, em vez da razão do WCAG 2
- O APCA Readability Criterion apresenta metas Bronze, Silver e Gold para ajudar na escolha de tamanho e peso da fonte
- No cálculo de exemplo, a combinação de texto branco com
#2DAD4E funciona com texto de 24px e font-weight 400 ou maior; para usar font-weight 300, seria preciso no mínimo 41px
- Para usuários que pediram contraste maior, é possível definir cores separadas para modo claro e modo escuro
- Modo claro: verde mais escuro com texto branco, Lc -76.1
- Modo escuro: verde mais claro com texto preto, Lc 75.2
--button-color: #2DAD4E; /* brand green background */
@media (prefers-contrast: more) {
@media (prefers-color-scheme: light) {
--button-color: #419543; /* darker green background */
}
@media (prefers-color-scheme: dark) {
--button-color: #77CA8B; /* lighter green background */
}
}
button {
background-color: var(--button-color);
color: contrast-color(var(--button-color));
font-size: 1.5rem; /* 1.5 * 16 = 24px at normal zoom */
font-weight: 500;
}
- Como hoje o algoritmo do WCAG 2 é o que move
contrast-color(), pode ser difícil usar esse recurso nesse site de exemplo
- Em projetos cuja cor de marca seja um verde mais escuro e onde a escolha entre preto e branco funcione corretamente, ele já pode ser útil agora
contrast-color() é especialmente útil ao definir cores para vários estados ou opções, como enabled/disabled, modo claro/escuro e prefers-contrast
Por que ele foi limitado primeiro à escolha entre preto e branco
- Atualmente,
contrast-color() foi bastante simplificado em relação ao color-contrast() do Safari Technology Preview 122
- Como a discussão sobre o algoritmo de contraste do WCAG 3 ainda não terminou, o CSS Working Group decidiu avançar primeiro com uma ferramenta que escolhe apenas preto ou branco em contraste com a cor de referência
- Fixar as opções em preto/branco reduz a chance de sites quebrarem no futuro caso o algoritmo do WCAG 2 mude
- No futuro, podem surgir ferramentas mais poderosas, como seleção pelo navegador a partir de uma lista de cores personalizada ou definição do nível de contraste desejado
contrast-color() pode ser usado não só para a cor do texto, mas também em várias propriedades que definem cores, como fundo e borda
Ainda não há comentários.