DEV Community

frontendfacile.it
frontendfacile.it

Posted on Originally published at frontendfacile.it

CSS alpha(): serve davvero o è solo zucchero sintattico?

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% */
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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%);
}
Enter fullscreen mode Exit fullscreen mode

Oppure, se preferisci ragionare in modo “diretto” sulla quantità di colore che rimane:

.card {
  border-color: color-mix(in oklch, var(--accent) 50%, transparent);
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

Il punto chiave è concettuale:

  • usa lo spazio colore del colore di partenza;
  • non devi riscrivere h s l o r 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à:

  1. Leggibilità: è molto più facile fare code review su alpha(from … / 0.2) rispetto a un color-mix() verboso o a un colore relativo che sembra “magico”.
  2. Meno decisioni non necessarie: quando vuoi solo trasparenza, dover scegliere uno spazio colore è un dettaglio che non aggiunge valore.
  3. 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);
}
Enter fullscreen mode Exit fullscreen mode

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)