Tre modi per ottenere trasparenze da un colore variabile: color-mix(), colori relativi e la nuova alpha().
Il problema: voglio lo stesso colore, ma con opacità diversa
Uno scenario ricorrente in UI design: hai un colore “base” (accent, brand, testo) salvato in una custom property e ti serve una sua variante più trasparente per ombre, bordi, hover, background “tinted”, focus ring… senza duplicare varianti e senza introdurre incoerenze.
Esempio tipico:
:root {
--accent: oklch(65% 0.18 145);
}
.button {
background: var(--accent);
}
/* ora voglio lo stesso colore al 50% */
La richiesta sembra banale, ma in CSS (storicamente) non lo è stata, soprattutto se il colore in variabile non è “smontato” in canali (r, g, b / h, s, l…).
Il vecchio trucco (con un difetto grosso)
Per anni la soluzione più comune è stata salvare solo i canali e poi “ricostruire” la funzione colore dove serve, così da poter cambiare l’alpha a piacere:
:root {
--accent-hsl: 145 70% 45%;
}
.card {
border-color: hsl(var(--accent-hsl) / 0.5);
}
Funziona, ma ha un problema strutturale: stai vincolando il formato del colore. Se domani cambi idea e vuoi esprimere l’accent in rgb() o in oklch(), devi rifare la variabile (e spesso anche tutte le occorrenze). Inoltre, il pattern “variabile dentro la funzione colore” è poco elegante e facile da rompere.
In pratica: comodo, ma fragile e poco flessibile.
Opzione moderna #1: color-mix() con transparent
Un approccio molto pulito è miscelare il colore con transparent:
.card {
border-color: color-mix(in oklch, var(--accent), transparent 50%);
}
Oppure, se preferisci ragionare in modo “diretto” sulla quantità di colore che rimane:
.card {
border-color: color-mix(in oklch, var(--accent) 50%, transparent);
}
Pro
- Non devi scomporre i canali.
- È espressivo: stai letteralmente “mischiando” verso la trasparenza.
Contro
- Devi scegliere (o specificare) lo spazio colore (
in oklch,in srgb, ecc.). - La lettura è un filo più verbosa.
Quando devi anche fare blending tra due colori reali (non solo trasparenza), color-mix() rimane imbattibile. Ma per “abbassa solo l’opacità”, può risultare ridondante.
Opzione moderna #2: colori relativi (relative colors)
I colori relativi permettono di prendere un colore esistente e ricostruirlo in un’altra funzione, impostando (tra le altre cose) l’alpha:
.card {
border-color: hsl(from var(--accent) h s l / 0.5);
}
Punto interessante: puoi usare una funzione diversa da quella originale. Anche se --accent fosse rgb() o oklch(), puoi comunque estrarre componenti e definire l’alpha.
Pro
- Potenti e flessibili (non solo alpha: anche trasformazioni su canali).
Contro
- Sintassi meno immediata per chi la vede la prima volta.
- Devi comunque “dichiarare” una funzione colore di destinazione, con i suoi canali.
Se fai color design sistematico (tinte, shade, manipolazioni percettive in OKLCH), i colori relativi sono uno strumento eccellente. Ma per il caso base “stesso colore, più trasparente”, possono sembrare eccessivi.
La novità: alpha()
alpha() fa esattamente una cosa: prende un colore e gli imposta un’opacità, senza costringerti a scegliere spazi colore o riscrivere canali.
.card {
border-color: alpha(from var(--accent) / 0.5);
}
Il punto chiave è concettuale:
- usa lo spazio colore del colore di partenza;
- non devi riscrivere
h s lor g b; - l’intento è immediato: “questo colore, a questa alpha”.
Perché non è solo un “doppione”
Sì, il risultato lo ottenevi già. Ma alpha() riduce attrito e ambiguità:
-
Leggibilità: è molto più facile fare code review su
alpha(from … / 0.2)rispetto a uncolor-mix()verboso o a un colore relativo che sembra “magico”. - Meno decisioni non necessarie: quando vuoi solo trasparenza, dover scegliere uno spazio colore è un dettaglio che non aggiunge valore.
- Meno varianti: facilita pattern tipo “un solo token colore, tante applicazioni con alpha diverse” (ombre, overlay, stati).
Esempio pratico:
:root {
--accent: #22c55e;
}
.button {
background: var(--accent);
box-shadow: 0 10px 30px alpha(from var(--accent) / 0.25);
}
.button:hover {
outline: 3px solid alpha(from var(--accent) / 0.45);
}
Quindi: quando usare cosa?
-
Hai bisogno di miscelare colori (non solo trasparenza)? Usa
color-mix(). - Vuoi manipolare canali (lightness, chroma, hue) o derivare scale coerenti? Usa colori relativi.
-
Vuoi semplicemente abbassare l’opacità di un colore esistente, mantenendolo “com’è”?
alpha()è la scelta più diretta.
Sintesi finale
alpha() non introduce una nuova capacità “impossibile” prima: introduce un modo più semplice e leggibile per un’operazione che in UI capita continuamente. In un codice dove i colori vivono in design token e custom properties, poter dire “questo colore, ma al 30%” senza scegliere spazi colore e senza riscrivere funzioni è un miglioramento concreto.
La conseguenza pratica è chiara: meno varianti nel sistema colori, meno CSS cerimoniale, e un’intenzione più esplicita in ogni regola. In un frontend che deve restare manutenibile nel tempo, questo tipo di zucchero sintattico è spesso esattamente ciò che serve.
Articolo originale: https://frontendfacile.it/blog/css-alpha-serve-davvero-o-e-solo-zucchero-sintattico
Top comments (0)