box-shadow prende quattro lunghezze e un colore, e il modo più rapido per capire cosa fa ognuna è trascinarla e guardare. La sintassi è offset-x, offset-y, sfocatura, espansione, colore — più la parola chiave opzionale inset, che ribalta l'ombra verso l'interno.
Un'ombra non occupa alcuno spazio
È la caratteristica più utile di questa proprietà ed è facile non accorgersene. Un'ombra viene dipinta, non impaginata. Dai a un elemento un'ombra con 80 pixel di sfocatura e 80 di espansione — un'ombra che si estende per 160 pixel in ogni direzione — e l'elemento accanto non si sposta di un solo pixel. Niente rifluisce, niente si muove.
È per questo che box-shadow è lo strumento giusto per gli anelli di focus e gli stati hover, e border è quello sbagliato. Aggiungere un bordo di 2px all'hover spinge di due pixel tutto ciò che sta intorno; aggiungere un'ombra di 2px no. Il vecchio trucco di applicare in anticipo un bordo trasparente per riservare lo spazio diventa inutile una volta che ricorri a un'ombra.
La sfocatura non è il numero che pensi
Il raggio di sfocatura non è la deviazione standard della sfocatura gaussiana: la specifica lo definisce come il doppio. Una sfocatura di 12px produce una gaussiana con sigma 6. La cosa conta esattamente quando stai cercando di far combaciare un'ombra con un design prodotto in Figma o Sketch, dove il valore di blur significa qualcosa di leggermente diverso, e il tuo CSS continua a venire più morbido o più stretto del mockup.
In pratica significa che l'ombra sfuma all'incirca lungo il raggio di sfocatura su ciascun lato del bordo. Una sfocatura di 12px è una transizione morbida larga circa 12 pixel, e l'estensione visibile dell'ombra è grossomodo l'offset più l'espansione più la sfocatura.
L'espansione è il parametro che tutti ignorano, negativa compresa
L'espansione ingrandisce o rimpicciolisce la forma dell'ombra prima di sfocarla. Un'espansione positiva rende l'ombra più grande dell'elemento, che si legge come una sorgente luminosa più lontana. Fin qui è semplice.
L'espansione negativa è quella interessante, ed è da lì che vengono le ombre realistiche. Un oggetto vicino a una superficie proietta un'ombra stretta e scura direttamente sotto di sé; un oggetto lontano ne proietta una grande e diffusa. L'elevazione vera assomiglia a un piccolo offset con espansione negativa, non a una grande sfocatura. Un'ombra 0 10px 10px -5px è più stretta e più credibile di 0 10px 20px 0: l'espansione negativa tira dentro i bordi, così l'ombra non sborda lateralmente da sotto l'elemento.
Una sola ombra raramente sta bene — e questo strumento ne fa una
Il CSS ti lascia separare con virgole quante ombre vuoi su un singolo elemento, ed è la differenza più grande tra un'ombra che sembra progettata e una che sembra un default del CSS. Gli oggetti veri non proiettano una sola ombra: ne proiettano una stretta e scura di contatto dove toccano la superficie, e una più ampia e morbida più in là.
Questo strumento costruisce una sola ombra, che è il modo giusto per imparare cosa fa ogni parametro. Quando poi la usi, stratificane due o tre: qualcosa come 0 1px 2px rgba(0,0,0,0.1), 0 4px 8px rgba(0,0,0,0.06) si legge come profondità in un modo che un singolo 0 4px 12px rgba(0,0,0,0.15) non raggiunge mai del tutto. Ogni strato dovrebbe diventare più grande e più trasparente man mano che si allontana.
Già che ci sei: le ombre sono più convincenti quando sono una versione scura della tinta dello sfondo invece che nero puro. Le ombre nere su una superficie colorata sembrano grigie e morte, perché le ombre vere sono zone dove arriva meno luce su una superficie che conserva comunque il proprio colore.
Non animarla
box-shadow non è una proprietà economica da animare. Ogni fotogramma costringe il browser a ridipingere l'ombra, e un'ombra sfocata è costosa da rasterizzare: animala su una lista di card e sentirai il frame rate calare su un telefono di fascia media.
Il rimedio standard è mettere l'ombra su uno pseudo-elemento, posizionarlo dietro la card, e animare l'opacità di quell'elemento. Le animazioni di opacità sono gestite dal compositor e non toccano mai la fase di paint, quindi il costo è pressoché zero a prescindere da quanto sia grande l'ombra. È un po' di markup in più per un hover fluido, ed è la differenza tra un'interfaccia che sembra solida e una che sobbalza.
Domande frequenti
Viene inviato qualcosa a un server?
No. Questo strumento è marcato "client": l'anteprima è il tuo browser che renderizza il CSS, e la regola generata è assemblata dai valori degli slider nella pagina. Non viene trasmesso niente.
Che differenza c'è tra box-shadow e filter: drop-shadow?
box-shadow segue il box dell'elemento: un rettangolo, o un rettangolo arrotondato se hai un border-radius. filter: drop-shadow segue la forma visibile reale, trasparenza inclusa. Quindi per un PNG con un logo ritagliato o un SVG irregolare, box-shadow disegna l'ombra del rettangolo attorno, che sta male, e drop-shadow traccia il contorno, che sta bene. Per normali card rettangolari, box-shadow costa meno e fa lo stesso lavoro.
Perché la mia ombra inset non si vede?
Di solito perché l'elemento ha uno sfondo dipinto sopra, o perché non ha dimensioni degne di nota. Un'ombra inset viene disegnata dentro il padding box, sopra lo sfondo ma sotto il contenuto: se l'elemento è vuoto e non ha altezza, non c'è niente su cui disegnare. Vale anche la pena controllare di non averla messa su un elemento il cui interno è coperto da un figlio che lo riempie del tutto.
Un'ombra può seguire un border-radius?
Sì, automaticamente. box-shadow usa la forma del border-box, quindi un elemento arrotondato ottiene un'ombra arrotondata senza lavoro extra. È uno dei motivi per cui box-shadow è preferibile a un'immagine d'ombra disegnata a mano: resta corretta quando il raggio cambia.
Come faccio un'ombra su un lato solo?
Spostala più di quanto la sfochi, e tira dentro i lati con un'espansione negativa. Qualcosa come 0 8px 6px -6px black produce un'ombra che compare solo sotto l'elemento: l'espansione negativa la restringe più stretta del box, l'offset la spinge giù, e la sfocatura ammorbidisce quel che resta. Provare a farlo con un semplice offset e senza espansione negativa lascerà sempre l'ombra che sbircia dai lati.