Il
modello di colore HSL
(hue, saturation, lightness - tonalità, saturazione, luminosità) offre agli sviluppatori un modo molto più leggibile per lavorare con i colori in CSS rispetto a RGB. Invece di indovinare quale combinazione di valori rosso, verde e blu produce la sfumatura desiderata, HSL ti permette di descrivere il colore nel modo in cui il tuo cervello lo percepisce naturalmente: scegli una tonalità, decidi quanto deve essere vivida, poi decidi quanto chiara o scura. Questo cambio di approccio mentale è esattamente il motivo per cui sempre più sviluppatori stanno abbandonando
rgb()
in favore di
hsl()
.
Indice dei contenuti
RGB vs HSL - La differenza fondamentale
RGB definisce il colore mescolando tre canali di luce: rosso, verde e blu, ciascuno su una scala da 0 a 255. Il problema è che questo riflette il modo in cui gli schermi renderizzano i pixel, non il modo in cui gli esseri umani percepiscono il colore. Se vuoi un blu leggermente più chiaro in RGB, devi aumentare tutti e tre i canali nella giusta proporzione - non esiste un singolo parametro da modificare.
HSL si adatta invece al modo in cui le persone descrivono il colore nella vita reale:
- Hue (tonalità) - il colore vero e proprio, espresso come grado su una ruota cromatica di 360 gradi. Il rosso è 0, il verde è 120, il blu è 240.
- Saturation (saturazione) - quanto il colore è vivido o spento, da 0% (grigio puro) a 100% (completamente saturo).
- Lightness (luminosità) - quanto il colore è chiaro o scuro, da 0% (nero) a 100% (bianco), con 50% che rappresenta il colore "puro".
Ecco lo stesso blu medio espresso in entrambi i formati:
/* RGB - what do these numbers even mean at a glance? */
color: rgb(70, 130, 180);
/* HSL - instantly readable: blue hue, moderate saturation, medium lightness */
color: hsl(207, 44%, 49%);
Entrambi producono lo stesso blu acciaio. Ma solo la versione HSL ti dice qualcosa di utile a colpo d'occhio. La tonalità è 207 (tendente al blu), la saturazione è moderata al 44%, e la luminosità si trova a metà scala al 49%. Puoi ragionarci sopra senza dover aprire un color picker.
| Proprietà | RGB | HSL |
|---|---|---|
| Leggibile dagli esseri umani | Raramente | Sì |
| Schiarire/scurire un colore | Modifica 3 valori | Modifica solo la luminosità |
| Cambiare la saturazione | Ricalcola tutti e 3 | Modifica solo la saturazione |
| Creare una palette di colori | Tentativi ed errori | Ruota la tonalità in gradi |
| Temi con variabili CSS | Verboso | Pulito e prevedibile |
Sintassi HSL in CSS
La funzione CSS
hsl()
è supportata fin da CSS3. La sintassi moderna (CSS Color Level 4) consente anche un quarto parametro alpha direttamente all'interno di
hsl()
, rendendo
hsla()
sostanzialmente ridondante:
/* Classic syntax */
color: hsl(207, 44%, 49%);
/* With alpha (transparency) - old way */
color: hsla(207, 44%, 49%, 0.8);
/* Modern CSS Color Level 4 syntax - commas optional, alpha with slash */
color: hsl(207 44% 49%);
color: hsl(207 44% 49% / 0.8);
color: hsl(207 44% 49% / 80%);
Tutti i browser principali supportano entrambe le sintassi. La versione senza virgole è la direzione verso cui si sta muovendo CSS, ma la versione con virgole funziona ovunque, incluso Internet Explorer 9+.
Perché HSL vince nello sviluppo UI
La vera potenza di HSL emerge nel momento in cui devi generare varianti di un colore - cosa che accade continuamente nel lavoro UI.
Costruire una palette di colori in pochi secondi
Supponiamo che il colore del tuo brand sia un verde vivido a
hsl(140, 70%, 45%)
. Hai bisogno di uno stato hover, uno stato disabilitato e una tinta di sfondo chiara. Con HSL, modifichi un solo valore ogni volta:
--color-base: hsl(140, 70%, 45%); /* base green */
--color-hover: hsl(140, 70%, 38%); /* darker - just lower lightness */
--color-disabled: hsl(140, 20%, 65%); /* washed out - lower saturation */
--color-tint: hsl(140, 70%, 92%); /* very light background tint */
Prova a farlo in modo prevedibile con RGB senza un color picker aperto. È genuinamente difficile perché non esiste un asse isolato su cui agire.
Colori analoghi e complementari
Poiché la tonalità è un grado su una ruota cromatica, generare palette armoniose è pura aritmetica. I colori analoghi si trovano entro 30 gradi l'uno dall'altro. I colori complementari distano 180 gradi:
--primary: hsl(210, 80%, 50%); /* blue */
--analogous-1: hsl(180, 80%, 50%); /* cyan - 30 degrees left */
--analogous-2: hsl(240, 80%, 50%); /* purple - 30 degrees right */
--complementary: hsl(30, 80%, 50%); /* orange - 180 degrees opposite */
La saturazione e la luminosità rimangono identiche, quindi i colori sembrano una famiglia coerente. È esattamente così che design system come Tailwind CSS e Material Design generano le loro scale cromatiche in modo programmatico.
Esempi pratici in CSS
Proprietà personalizzate CSS con componenti HSL
Uno dei pattern HSL più potenti consiste nel separare i tre valori in proprietà personalizzate CSS distinte. Questo ti permette di ricomporli ovunque e di modificare i singoli canali al volo:
:root {
--brand-h: 210;
--brand-s: 80%;
--brand-l: 50%;
--brand-color: hsl(var(--brand-h), var(--brand-s), var(--brand-l));
}
.button {
background-color: var(--brand-color);
}
.button:hover {
/* Just override lightness - no need to redefine the whole color */
background-color: hsl(var(--brand-h), var(--brand-s), 40%);
}
.button:disabled {
background-color: hsl(var(--brand-h), 20%, 70%);
}
hsl()
, è necessario usare le virgole:
hsl(var(--h), var(--s), var(--l))
. La sintassi moderna senza virgole non funziona ancora con
var()
all'interno di
hsl()
in tutti i browser.
Generare una scala tonale completa
I design system spesso richiedono 9-10 sfumature di un singolo colore (come la scala da 50 a 950 di Tailwind). Con HSL, puoi generare l'intera scala incrementando la luminosità a intervalli regolari, mantenendo fissi tonalità e saturazione:
:root {
--blue-50: hsl(210, 80%, 95%);
--blue-100: hsl(210, 80%, 87%);
--blue-200: hsl(210, 80%, 76%);
--blue-300: hsl(210, 80%, 65%);
--blue-400: hsl(210, 80%, 55%);
--blue-500: hsl(210, 80%, 50%); /* base */
--blue-600: hsl(210, 80%, 43%);
--blue-700: hsl(210, 80%, 36%);
--blue-800: hsl(210, 80%, 26%);
--blue-900: hsl(210, 80%, 16%);
}
Per un approfondimento su come i formati colore si relazionano tra loro, la guida alla conversione da HEX a RGB offre un quadro completo dei formati colore in CSS, incluso quando ciascuno è lo strumento giusto da usare.
Stato hover, temi e dark mode
Stati hover e focus
Con HSL, gestire gli stati hover diventa banale. Invece di definire un colore completamente separato, ti basta modificare la luminosità:
.btn-primary {
background: hsl(210, 80%, 50%);
transition: background 0.2s ease;
}
.btn-primary:hover { background: hsl(210, 80%, 43%); }
.btn-primary:active { background: hsl(210, 80%, 36%); }
.btn-primary:focus-visible {
outline: 3px solid hsl(210, 80%, 70%);
}
Ogni stato è chiaramente correlato al colore base. Un collega che legge questo codice capisce immediatamente la relazione tra i vari stati.
Temi con variabili HSL
HSL è la base del theming CSS moderno. Esponendo solo la tonalità come variabile, puoi permettere a utenti o amministratori di cambiare l'intera palette cromatica di un'applicazione modificando un solo numero:
/* Default theme: blue */
:root {
--theme-hue: 210;
}
/* Green theme - just swap the hue */
[data-theme="green"] {
--theme-hue: 140;
}
/* Purple theme */
[data-theme="purple"] {
--theme-hue: 270;
}
/* All components use the same hue variable */
.button { background: hsl(var(--theme-hue), 75%, 50%); }
.link { color: hsl(var(--theme-hue), 75%, 40%); }
.badge { background: hsl(var(--theme-hue), 75%, 92%); color: hsl(var(--theme-hue), 75%, 25%); }
.focus-ring { outline-color: hsl(var(--theme-hue), 75%, 65%); }
Dark mode con HSL
La dark mode è il contesto in cui HSL dà il meglio di sé. Invece di mantenere due palette di colori completamente separate, si invertono i valori di luminosità all'interno della stessa tonalità:
:root {
--bg: hsl(210, 20%, 98%); /* near-white background */
--text: hsl(210, 20%, 15%); /* near-black text */
--card: hsl(210, 20%, 93%); /* slightly darker card */
}
@media (prefers-color-scheme: dark) {
:root {
--bg: hsl(210, 20%, 10%); /* flip: near-black background */
--text: hsl(210, 20%, 90%); /* flip: near-white text */
--card: hsl(210, 20%, 15%); /* slightly lighter card in dark */
}
}
Nota che la tonalità (210) e la saturazione (20%) non cambiano mai. Solo la luminosità si inverte. Questo mantiene la dark mode coerente con il design originale, semplicemente invertito - ed è esattamente quello che una buona dark mode dovrebbe fare.
Supporto browser e compatibilità
HSL gode di un ottimo supporto nei browser. La funzione
hsl()
è disponibile fin da:
- Chrome 1 (2008)
- Firefox 1 (2004)
- Safari 3.1 (2008)
- Internet Explorer 9 (2011)
- Edge 12 (2015)
La sintassi moderna senza virgole (
hsl(210 80% 50%)
) e la sintassi con slash per l'alpha (
hsl(210 80% 50% / 0.5)
) fanno parte della
specifica CSS Color Level 4
e sono supportate in tutti i browser moderni dal 2023. Se hai ancora bisogno di supportare IE11 (caso sempre più raro), usa la sintassi con virgole.
hsl()
con virgole funziona in ogni browser che i tuoi utenti probabilmente stanno usando. La sintassi moderna con spazi funziona in Chrome 90+, Firefox 89+ e Safari 14.1+, coprendo oltre il 95% dell'utilizzo globale dei browser.
Puoi sempre usare un color picker per convertire tra i formati HSL, RGB e HEX quando hai bisogno di confrontare valori o passare i colori a strumenti che accettano solo un formato specifico.
HSL vs OKLCH - Cosa ci aspetta?
Se vuoi andare oltre HSL, OKLCH merita attenzione. È uno spazio colore percettivamente uniforme, il che significa che passi numerici uguali nella luminosità o nella chroma corrispondono effettivamente a variazioni visivamente uguali per l'occhio umano - qualcosa che HSL non garantisce del tutto.
Il limite di HSL è che due colori con lo stesso valore di luminosità possono sembrare molto diversi in termini di luminosità percepita. Ad esempio,
hsl(60, 100%, 50%)
(giallo) appare molto più luminoso di
hsl(240, 100%, 50%)
(blu), anche se entrambi hanno il 50% di luminosità. OKLCH corregge questo comportamento.
/* HSL - same lightness, different perceived brightness */
color: hsl(60, 100%, 50%); /* yellow - looks very bright */
color: hsl(240, 100%, 50%); /* blue - looks much darker */
/* OKLCH - same lightness, actually looks the same to the eye */
color: oklch(0.75 0.18 90); /* yellow-ish */
color: oklch(0.75 0.18 260); /* blue-ish - genuinely similar perceived brightness */
OKLCH supporta anche i
colori wide-gamut
(colori display P3) che vanno oltre il range sRGB a cui HSL è limitato. Il supporto browser per
oklch()
è solido nel 2024: Chrome 111+, Firefox 113+, Safari 15.4+.
Per la maggior parte dei progetti attuali, HSL rappresenta il punto di equilibrio ideale: leggibile, manutenibile, universalmente supportato e un enorme miglioramento rispetto a RGB. OKLCH è la scelta giusta quando stai costruendo un design system che richiede rapporti di contrasto matematicamente coerenti o quando vuoi supportare display wide-gamut.
Se stai esplorando visivamente le relazioni tra i colori mentre costruisci la tua palette, il color explorer ti permette di sperimentare con i valori HSL e vedere in tempo reale come interagiscono rotazioni di tonalità, variazioni di saturazione e cambiamenti di luminosità.
Scegli i colori HSL senza dover indovinare
Il nostro color picker ti permette di regolare visivamente i valori di tonalità, saturazione e luminosità, per poi copiare direttamente nel tuo CSS l'output del modello di colore HSL - senza calcoli mentali.
Prova il Color Picker →
Non è necessario fare una riscrittura completa, ma vale la pena passare a HSL per tutte le nuove definizioni di colore che scrivi, soprattutto quando usi proprietà personalizzate CSS. I guadagni maggiori si ottengono quando stai costruendo o mantenendo un design system, creando stati hover o implementando la dark mode. Mescolare RGB e HSL nello stesso progetto è CSS perfettamente valido - i browser gestiscono entrambi senza alcuna differenza di prestazioni.
No, non esiste alcuna differenza di prestazioni significativa. Il browser converte tutti i formati colore CSS in una rappresentazione interna al momento del parsing, quindi che tu scriva
hsl(207, 44%, 49%)
o
rgb(70, 130, 180)
, il motore di rendering li tratta in modo identico dopo quel passaggio iniziale. La scelta riguarda esclusivamente l'esperienza dello sviluppatore e la manutenibilità, non le prestazioni a runtime.
Sì, e questo è uno dei casi d'uso più potenti di HSL in JavaScript. Puoi memorizzare tonalità, saturazione e luminosità come numeri separati, poi costruire la stringa del colore dinamicamente:
element.style.color = `hsl(${hue}, ${saturation}%, ${lightness}%)`
. Questo rende animazioni, cambio di tema e controlli interattivi del colore molto più semplici da implementare rispetto al lavoro con i canali RGB, dove avresti bisogno di matematica di conversione per ottenere gli stessi effetti.
HSL (hue, saturation, lightness) e HSB/HSV (hue, saturation, brightness/value) sono modelli di colore diversi anche se condividono l'asse della tonalità. In HSL, una luminosità del 50% corrisponde al colore puro e completamente saturo. In HSB, una luminosità del 100% dà il colore puro. I due modelli producono risultati diversi per gli stessi valori di saturazione e luminosità. CSS utilizza specificamente HSL - HSB/HSV è comune negli strumenti di design come Photoshop e Figma, ma non è un formato CSS nativo.
La conversione da HEX a HSL passa attraverso un passaggio intermedio in RGB: prima si convertono le coppie HEX in valori RGB (0-255), poi si normalizzano a 0-1, infine si applica la formula di conversione HSL. In pratica, la maggior parte degli sviluppatori usa un color picker, uno strumento di design come Figma, o il color picker nei DevTools del browser per farlo istantaneamente, invece di calcolarlo a mano. I DevTools del browser ti permettono di cliccare su qualsiasi campione di colore e scorrere tra le rappresentazioni HEX, RGB e HSL.
Sì, OKLCH è più affidabile per il lavoro sull'accessibilità perché è percettivamente uniforme - passi uguali nel suo canale di luminosità corrispondono a variazioni di luminosità percepita uguali. Questo rende più semplice costruire palette di colori in cui i rapporti di contrasto siano prevedibili tra diverse tonalità. Con HSL, il giallo al 50% di luminosità appare molto più luminoso del blu al 50% di luminosità, il che può portare a sorprese in termini di accessibilità. Per la conformità al contrasto WCAG, OKLCH offre risultati più prevedibili quando si costruiscono scale cromatiche accessibili.