Ecco un numero a cui continuo a tornare: nel report WebAIM Million del 2025, il testo a basso contrasto è stato il singolo errore di accessibilità più comune del web, presente sul 79,1% del milione di home page più visitate. Non l'alt text mancante. Non i pulsanti privi di etichetta. Il contrasto. Il problema di accessibilità più rilevato al mondo è costituito da due colori troppo simili, e quasi ogni team che lo pubblica non ha idea di averlo fatto.
Questo bug l'ho pubblicato anch'io. Anni fa costruii una dashboard "premium" con un elegante testo grigio #9CA3AF su bianco, approvata da tutti i presenti perché appariva raffinata su un display Retina nuovo di zecca in una sala riunioni in penombra. Una settimana dopo arrivò un ticket di assistenza da un utente su un treno illuminato dal sole che letteralmente non riusciva a leggere le etichette. Il testo era a circa 2.6:1. Le WCAG chiedono 4.5:1. Quel divario è l'intero argomento di questo articolo.
Cos'è davvero un rapporto di contrasto WCAG
Un rapporto di contrasto WCAG è un singolo numero che descrive quanto due colori siano diversi in luminosità, espresso come un rapporto da 1:1 a 21:1. Bianco su bianco è 1:1 (invisibile). Nero puro su bianco puro è 21:1 (il massimo). Tutto ciò che progetti vive da qualche parte nel mezzo, e le WCAG fissano il pavimento sotto il quale non ti è consentito scendere.
La cosa cruciale da interiorizzare subito: il contrasto riguarda la luminanza, non il fatto che i colori "sembrino diversi". Il rosso e il verde sembrano profondamente diversi alla maggior parte delle persone, ma un rosso saturo (#FF0000) su un verde saturo (#008000) si attesta solo intorno a 1.3:1 perché portano una luminosità quasi identica. Per una persona con daltonismo rosso-verde, o per chiunque dia un'occhiata su uno schermo di bassa qualità, quell'abbinamento è un pasticcio. Il tuo occhio è ingannato dalla tinta; la formula del contrasto no.
La formula, in parole semplici
Il rapporto è calcolato come (L1 + 0.05) / (L2 + 0.05), dove L1 è la luminanza relativa del colore più chiaro e L2 la luminanza di quello più scuro. Non lo calcolerai quasi mai a mano, ma capire le due fasi ti spiega perché il tuo istinto ti inganna.
Prima, la luminanza relativa di ogni colore si ottiene prendendo i suoi canali rosso, verde e blu, "linearizzandoli" (annullando la curva di gamma che gli schermi applicano, con la regola che i canali pari o inferiori a 0.03928 vengono divisi per 12.92 e quelli più alti passano attraverso ((c + 0.055) / 1.055) ^ 2.4), e poi pesandoli: 0.2126 per il rosso, 0.7152 per il verde e 0.0722 per il blu. Questi pesi non sono arbitrari. L'occhio umano è straordinariamente sensibile al verde e quasi cieco al blu in confronto.
Questa è la conclusione più utile della matematica: il verde porta all'incirca dieci volte la luminosità percepita del blu. Ecco perché il testo blu puro su nero è doloroso e passa a malapena, mentre la stessa "oscurità" di verde si legge bene. È il motivo per cui i tuoi link blu su uno sfondo scuro sembrano deboli per quanto tu li renda saturi. Se ricordi una sola cosa della formula, ricorda i pesi.
Lo + 0.05 nel rapporto è una costante che modella la luce ambientale riflessa dallo schermo, così che persino neri teoricamente perfetti non producano mai un rapporto infinito. È la ragione per cui i rapporti di contrasto si fermano a 21:1.
Le tre soglie che devi conoscere
Le WCAG (le Web Content Accessibility Guidelines, mantenute dal W3C) definiscono un piccolo insieme di numeri. Memorizza questi e avrai coperto la stragrande maggioranza del lavoro reale.
- 4.5:1 — il minimo per il testo del corpo normale al livello AA. È il numero da cavallo di battaglia. Se punti a un solo valore, punta a questo.
- 3:1 — il minimo per il testo grande in AA, e anche il minimo per gli elementi di interfaccia non testuali e la grafica (di più sotto).
- 7:1 — testo normale al livello AAA, il livello potenziato per gli utenti con ipovisione. Il testo grande in AAA richiede 4.5:1.
Nota lo schema: ogni livello è all'incirca quello successivo. Large-AA e non-testuale condividono 3:1; normal-AA e large-AAA condividono 4.5:1. C'è meno da ricordare di quanto sembri.
AA contro AAA: quale devi effettivamente garantire?
AA è lo standard del mondo reale. È quello a cui fanno riferimento l'European Accessibility Act, i contenziosi spinti dall'ADA negli Stati Uniti, la Section 508 e praticamente ogni contratto di fornitura. Quando un avvocato o un revisore dice "conforme alle WCAG", intende AA. AAA è il livello d'oro, e le linee guida stesse affermano esplicitamente che la conformità AAA non è richiesta come politica generale per interi siti, in parte perché alcuni contenuti semplicemente non possono raggiungere 7:1 senza apparire rotti.
La mia opinione onesta dopo anni di questo lavoro: progetta il testo del corpo perché superi comodamente AA, poi tratta AAA come un obiettivo da centrare per i contenuti che contano di più — la colonna di lettura principale di un articolo, i messaggi di errore, qualsiasi cosa che un utente sotto stress o con ipovisione debba decifrare sotto pressione. Inseguire 7:1 su ogni didascalia ed etichetta disabilitata è una battaglia persa che appiattisce tutta la tua palette in nero-su-bianco.
Testo normale contro testo grande — e la trappola che vi è nascosta
Le WCAG sono più indulgenti con il testo grande (3:1 anziché 4.5:1) perché lettere più grandi e pesanti sono leggibili a un contrasto inferiore. Ma la definizione di "grande" è specifica e la gente la sbaglia di continuo.
- Grande = da 18pt in su, ovvero 24px a peso normale.
- Oppure da 14pt in su, ovvero circa 18,5px, se il testo è in grassetto.
La conversione che inciampa tutti è 1pt = 1.333px, ed è per questo che 18pt diventa 24px e 14pt diventa ~18,5px. Quindi un titolo regular da 19px non è testo grande secondo la definizione delle WCAG — deve comunque garantire il pieno 4.5:1. Anche un'etichetta in grassetto da 16px non è grande. Ho visto design "passare" nella testa di qualcuno perché il titolo "sembrava grande", quando in pixel si attestava appena sotto la soglia e necessitava del rapporto più severo. In caso di dubbio, tieni corpo e sottotitoli a 4.5:1 e rivendica la deroga del 3:1 solo per testo display genuinamente grande.
Contrasto non testuale: il criterio che tutti dimenticano (1.4.11)
È qui che falliscono la maggior parte dei team altrimenti attenti. Le WCAG 2.1 hanno aggiunto il criterio di successo 1.4.11, Contrasto non testuale, che richiede 3:1 per due categorie che non hanno nulla a che fare con la lettura:
- Componenti di interfaccia utente — il confine visivo di un controllo che ti dice che esiste e in quale stato si trova. Il bordo di un campo di testo, il contorno di una checkbox non spuntata, il focus ring attorno a un pulsante, il binario di un interruttore.
- Oggetti grafici — le parti di icone, grafici e diagrammi necessarie a comprenderli. La linea in uno sparkline, le fette di un grafico a torta, la forma di un'icona di avviso.
La violazione classica: un campo di ricerca che è solo un riquadro #FFFFFF con un bordo grigio chiaro #E5E7EB da 1px su una pagina bianca. Quel bordo è circa 1.2:1. Gli utenti vedenti con ipovisione letteralmente non riescono a trovare dove cliccare. Il testo placeholder pallido e i contorni dei ghost button falliscono allo stesso modo. La pura decorazione è esente, e così pure il testo all'interno del componente (che ricade invece sotto 1.4.3) — ma ciò che segnala "questo è interattivo" deve raggiungere 3:1 rispetto a qualunque cosa gli stia accanto.
Come misurarlo — e come correggerlo
Il contrasto non si valuta a occhio. Si misura. Il mio flusso di lavoro quotidiano:
- Nel browser, apri i DevTools e ispeziona l'elemento di testo. Sia Chrome che Firefox stampano il rapporto di contrasto direttamente nel selettore colore, con spunte per AA e AAA, e tracciano persino una linea sullo spazio colore che mostra la soglia che puoi trascinare.
- Per controllare una coppia di codici esadecimali prima ancora che finiscano nel codice, usa un checker dedicato. Il generatore di palette di colori su questo sito include un controllo del contrasto WCAG, così puoi validare le combinazioni mentre le stai ancora scegliendo, invece di scoprire il problema in un audit.
- Per analisi sull'intera pagina, esegui uno strumento automatico. Ma conoscine il limite: l'automazione coglie il testo su colore pieno e perde il testo posto su foto, gradienti od overlay semitrasparenti. Quelli li verifichi a mano.
Quando qualcosa fallisce, resisti alla tentazione di ritoccare la tinta. Cambiare la saturazione sposta a malapena il contrasto; cambiare la luminosità lo sposta molto. In concreto:
- Scurisci il primo piano o schiarisci lo sfondo finché non superi la linea. Il mio grigio
#9CA3AFdi prima doveva passare a circa#6B7280su bianco per raggiungere ~4.5:1 — stessa famiglia, solo qualche gradino più in profondità. - Per testo chiaro su colore, è di solito più rapido intensificare lo sfondo. Un'etichetta
#FFFFFFsu un pulsante blu#60A5FAfallisce; porta il pulsante a#2563EBe superi AA senza toccare il testo. - Per grafici e icone, aggiungi un sottile tratto più scuro o una leggera tonalizzazione di sfondo anziché lottare per rendere scuro ogni riempimento.
Gli errori che vedo nei team reali
- Approvare su uno schermo perfetto. Un MacBook immacolato in una stanza in penombra lusinga tutto. Gli utenti reali hanno riflessi, pannelli economici, filtri per la luce blu e il "night shift" che scalda i bianchi. Progetta per la peggiore condizione di visione plausibile, non per la demo.
- Fidarsi della tinta più che della luminanza. Due colori vividi ma di pari luminosità (di nuovo quel rosso-su-verde) possono essere invisibili agli utenti daltonici pur superando il tuo controllo a istinto. Calcola il numero.
- Dimenticare il testo placeholder e gli stati disabilitati. I placeholder sono comunque testo e devono comunque garantire il contrasto se trasmettono un significato. I controlli disabilitati sono genuinamente esenti, ma non abusarne per nascondere contenuti attivi a basso contrasto dietro un aspetto "disabilitato".
- Ignorare gli overlay. Il testo bianco su una foto hero passa sopra l'angolo scuro e fallisce sopra il cielo luminoso. Uno scrim — uno strato scuro semiopaco tra immagine e testo — è la soluzione standard.
- Trattare 4.5:1 come un obiettivo anziché come un pavimento. Atterrare esattamente su 4.5:1 è fragile; basta un designer che ritocca una sfumatura per romperlo di nuovo. Lasciati un margine.
Una parola sul futuro: le WCAG 3 stanno esplorando un modello percettivo chiamato APCA che giudica il contrasto più come fa l'occhio umano, tenendo conto insieme della dimensione e del peso del testo anziché di un rapporto piatto. È promettente e vale la pena tenerlo d'occhio, ma a oggi i rapporti di questo articolo — supportati da Understanding 1.4.3 del W3C — sono ciò che ti rende conforme legalmente e praticamente. Progetta secondo quelli, lasciati un margine e misura invece di tirare a indovinare. Il 79,1% dei siti che falliscono ha fallito perlopiù perché nessuno ha controllato. Controllare è l'intero lavoro.
Domande frequenti
Qual è il rapporto di contrasto WCAG minimo per il testo normale?
Il testo del corpo normale ha bisogno di un rapporto di contrasto di almeno 4.5:1 rispetto al suo sfondo per soddisfare il livello AA delle WCAG, lo standard a cui fa riferimento la maggior parte delle leggi e dei contratti. Il testo grande (18pt/24px regular, oppure 14pt/~18,5px in grassetto) richiede solo 3:1. Il livello AAA, più severo, alza il testo normale a 7:1 e il testo grande a 4.5:1.
Qual è la differenza tra il contrasto WCAG AA e AAA?
AA è lo standard pratico e di riferimento legale: 4.5:1 per il testo normale e 3:1 per il testo grande. AAA è il livello potenziato per gli utenti con ipovisione: 7:1 per il testo normale e 4.5:1 per il testo grande. Il W3C non richiede AAA per l'intero sito, quindi la maggior parte dei team costruisce il testo del corpo in AA con un margine e riserva AAA ai contenuti di lettura più critici.
Cosa conta come testo grande secondo le WCAG?
Il testo grande è da 18pt in su (24px) a peso normale, oppure da 14pt in su (circa 18,5px) se in grassetto. La conversione è 1pt = 1,333px. Un errore comune è dare per scontato che un titolo che semplicemente sembra grande sia idoneo — un titolo regular da 19px o 20px è comunque sotto i 24px e deve soddisfare il pieno 4.5:1 del testo normale.
Le WCAG richiedono il contrasto per pulsanti e icone, non solo per il testo?
Sì. Il criterio di successo 1.4.11 (Contrasto non testuale), aggiunto nelle WCAG 2.1, richiede un rapporto di 3:1 per i bordi dei componenti di interfaccia che indicano uno stato — contorni dei campi, focus ring, riquadri delle checkbox — e per gli oggetti grafici come le forme delle icone e gli elementi dei grafici necessari a comprenderli. La pura decorazione è esente.
Come correggo un testo che non supera la verifica del contrasto?
Modifica la luminosità, non la tinta o la saturazione — queste spostano a malapena il rapporto. Scurisci il primo piano o schiarisci lo sfondo finché non superi la soglia; per testo chiaro su un pulsante colorato è di solito più rapido intensificare il colore di sfondo. Misura il risultato con un controllo del contrasto anziché valutarlo a occhio, dato che le differenze di tinta ingannano l'occhio ma non la formula della luminanza.
Vuoi sperimentare con i colori?
Prova il nostro generatore di palette gratuito per trovare la tua armonia perfetta — con verifica del contrasto WCAG integrata.
Apri il generatore