Ferramentas / Conversor de cores e contraste WCAG

Conversor de cores e contraste WCAG

Converta HEX, RGB e HSL e confira se o contraste entre duas cores atende às regras de acessibilidade AA e AAA.

Converter HEX, RGB e HSL

Contraste WCAG entre duas cores

Razão de contraste: -

-

Processamento local: nada do que você digita sai do seu navegador.

Como usar

Digite uma cor em HEX (#0d6efd), rgb(13, 110, 253) ou hsl(216, 98%, 52%), ou escolha no seletor. Os três formatos aparecem prontos para copiar. Na segunda caixa, informe a cor do texto e do fundo para ver a razão de contraste.

Contraste WCAG

As diretrizes WCAG pedem razão mínima de 4,5:1 para texto normal e 3:1 para texto grande (nível AA). No nível AAA, os mínimos sobem para 7:1 e 4,5:1. Texto grande é a partir de 24px, ou 18,66px em negrito.

Como implementar em código

Exemplos prontos para usar no seu projeto.

// HEX -> RGB e contraste WCAG entre duas cores
const rgb = (hex) => hex.replace('#', '').match(/../g).map((h) => parseInt(h, 16));
const lum = (c) => c.map((v) => {
  v /= 255;
  return v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
}).reduce((a, v, i) => a + v * [0.2126, 0.7152, 0.0722][i], 0);

function contraste(hexA, hexB) {
  const [hi, lo] = [lum(rgb(hexA)), lum(rgb(hexB))].sort((a, b) => b - a);
  return (hi + 0.05) / (lo + 0.05);
}
console.log(contraste('#000000', '#ffffff')); // 21 (AA: >= 4.5, AAA: >= 7)
def rgb(hex_):
    h = hex_.lstrip("#")
    return [int(h[i:i + 2], 16) for i in (0, 2, 4)]

def luminancia(c):
    def f(v):
        v /= 255
        return v / 12.92 if v <= 0.03928 else ((v + 0.055) / 1.055) ** 2.4
    r, g, b = map(f, c)
    return 0.2126 * r + 0.7152 * g + 0.0722 * b

def contraste(a, b):
    hi, lo = sorted((luminancia(rgb(a)), luminancia(rgb(b))), reverse=True)
    return (hi + 0.05) / (lo + 0.05)

print(contraste("#000000", "#ffffff"))  # 21.0
package main

import "math"

func canal(v int) float64 {
	c := float64(v) / 255
	if c <= 0.03928 {
		return c / 12.92
	}
	return math.Pow((c+0.055)/1.055, 2.4)
}

func luminancia(r, g, b int) float64 {
	return 0.2126*canal(r) + 0.7152*canal(g) + 0.0722*canal(b)
}

// Razão de contraste WCAG entre duas luminâncias
func contraste(l1, l2 float64) float64 {
	if l1 < l2 {
		l1, l2 = l2, l1
	}
	return (l1 + 0.05) / (l2 + 0.05)
}
import 'dart:math';

double canal(int v) {
  final c = v / 255;
  return c <= 0.03928 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4).toDouble();
}

double luminancia(int r, int g, int b) =>
    0.2126 * canal(r) + 0.7152 * canal(g) + 0.0722 * canal(b);

/// Razão de contraste WCAG entre duas luminâncias
double contraste(double a, double b) =>
    (max(a, b) + 0.05) / (min(a, b) + 0.05);

// Em Flutter, Color.computeLuminance() é uma aproximação equivalente.
public class Cores {
    static double canal(int v) {
        double c = v / 255.0;
        return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
    }

    static double luminancia(int r, int g, int b) {
        return 0.2126 * canal(r) + 0.7152 * canal(g) + 0.0722 * canal(b);
    }

    // Razão de contraste WCAG entre duas luminâncias
    static double contraste(double a, double b) {
        return (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05);
    }
}
<?php
function canal(int $v): float {
    $c = $v / 255;
    return $c <= 0.03928 ? $c / 12.92 : (($c + 0.055) / 1.055) ** 2.4;
}

function luminancia(int $r, int $g, int $b): float {
    return 0.2126 * canal($r) + 0.7152 * canal($g) + 0.0722 * canal($b);
}

// Razão de contraste WCAG entre duas luminâncias
function contraste(float $a, float $b): float {
    return (max($a, $b) + 0.05) / (min($a, $b) + 0.05);
}
using System;

static double Canal(int v)
{
    double c = v / 255.0;
    return c <= 0.03928 ? c / 12.92 : Math.Pow((c + 0.055) / 1.055, 2.4);
}

static double Luminancia(int r, int g, int b) =>
    0.2126 * Canal(r) + 0.7152 * Canal(g) + 0.0722 * Canal(b);

// Razão de contraste WCAG entre duas luminâncias
static double Contraste(double a, double b) =>
    (Math.Max(a, b) + 0.05) / (Math.Min(a, b) + 0.05);

Perguntas frequentes

Qual a diferença entre RGB e HSL?

RGB mistura vermelho, verde e azul (0 a 255). HSL descreve a cor por matiz (0 a 360 graus), saturação e luminosidade em porcentagem, o que facilita criar variações mais claras ou escuras.

Como o contraste é calculado?

Usamos a fórmula do WCAG 2.x: calculamos a luminância relativa de cada cor e dividimos (maior + 0,05) pela (menor + 0,05).

Cores com transparência (alfa) são suportadas?

Aceitamos HEX com 4 ou 8 dígitos e rgba()/hsla(), mas o canal alfa é ignorado na conversão.

Veja também

Precisa de um sistema ou app sob medida?

A VcInova desenvolve software, aplicativos e integrações para empresas de todo o Brasil.

Fale com a VcInova