box-shadow prend quatre longueurs et une couleur, et le moyen le plus rapide de comprendre ce que fait chacune est de la faire glisser et de regarder. La syntaxe est offset-x, offset-y, flou, étalement, couleur — plus le mot-clé facultatif inset, qui bascule l'ombre vers l'intérieur.
Une ombre n'occupe aucune place
C'est la caractéristique la plus utile de cette propriété, et elle passe facilement inaperçue. Une ombre est peinte, pas mise en page. Donnez à un élément une ombre avec 80 pixels de flou et 80 pixels d'étalement — une ombre s'étendant sur 160 pixels dans toutes les directions — et l'élément voisin ne bouge pas d'un seul pixel. Rien ne se recalcule, rien ne se décale.
C'est pourquoi box-shadow est le bon outil pour les anneaux de focus et les états de survol, et border le mauvais. Ajouter une bordure de 2px au survol pousse de deux pixels tout ce qui l'entoure ; ajouter une ombre de 2px non. Le vieux truc consistant à poser d'avance une bordure transparente pour réserver la place devient inutile dès qu'on passe à une ombre.
Le flou n'est pas le nombre que vous croyez
Le rayon de flou n'est pas l'écart-type du flou gaussien — la spécification le définit comme son double. Un flou de 12px produit une gaussienne d'un sigma de 6. Cela compte précisément quand vous tentez d'accorder une ombre à une maquette réalisée sous Figma ou Sketch, où la valeur de flou signifie quelque chose de légèrement différent, et où votre CSS sort toujours plus doux ou plus serré que la maquette.
En pratique, l'ombre s'estompe sur environ le rayon de flou de chaque côté du bord. Un flou de 12px est une transition douce d'environ 12 pixels de large, et l'étendue visible de l'ombre vaut grosso modo le décalage plus l'étalement plus le flou.
L'étalement est le paramètre que tout le monde ignore, y compris négatif
L'étalement agrandit ou rétrécit la forme de l'ombre avant de la flouter. Un étalement positif rend l'ombre plus grande que l'élément, ce qui se lit comme une source lumineuse plus éloignée. Jusque-là, c'est simple.
L'étalement négatif est l'intéressant, et c'est de là que viennent les ombres réalistes. Un objet proche d'une surface projette une ombre serrée et sombre juste dessous ; un objet éloigné en projette une grande et diffuse. La vraie élévation ressemble à un petit décalage avec étalement négatif, pas à un grand flou. Une ombre 0 10px 10px -5px est plus serrée et plus crédible que 0 10px 20px 0 — l'étalement négatif rentre les bords, si bien que l'ombre ne déborde pas latéralement sous l'élément.
Une seule ombre rend rarement bien — cet outil en fait une
CSS vous laisse séparer par des virgules autant d'ombres que vous voulez sur un même élément, et c'est la plus grande différence entre une ombre qui a l'air conçue et une qui a l'air d'un réglage par défaut. Les objets réels ne projettent pas une ombre ; ils projettent une ombre de contact serrée et sombre là où ils touchent la surface, et une plus large et douce au-delà.
Cet outil construit une ombre unique, ce qui est la bonne façon d'apprendre le rôle de chaque paramètre. Au moment de vous en servir, superposez-en deux ou trois : quelque chose comme 0 1px 2px rgba(0,0,0,0.1), 0 4px 8px rgba(0,0,0,0.06) se lit comme de la profondeur d'une manière qu'un seul 0 4px 12px rgba(0,0,0,0.15) n'atteint jamais tout à fait. Chaque couche doit devenir plus grande et plus transparente à mesure qu'elle s'éloigne.
Tant qu'on y est : les ombres sont plus convaincantes quand elles sont une version sombre de la teinte du fond plutôt que du noir pur. Les ombres noires sur une surface colorée paraissent grises et mortes, car les vraies ombres sont des zones où moins de lumière atteint une surface qui garde tout de même sa couleur.
Ne l'animez pas
box-shadow n'est pas une propriété bon marché à animer. Chaque image force le navigateur à repeindre l'ombre, et une ombre floutée coûte cher à pixelliser — animez-la sur une liste de cartes et vous sentirez la fréquence d'images chuter sur un téléphone de milieu de gamme.
Le correctif standard consiste à poser l'ombre sur un pseudo-élément, à le placer derrière la carte, et à animer l'opacité de cet élément. Les animations d'opacité sont prises en charge par le compositeur et ne touchent jamais l'étape de peinture : le coût est donc quasi nul, quelle que soit la taille de l'ombre. Un peu de balisage en plus pour un survol fluide, et c'est la différence entre une interface qui semble solide et une qui saccade.
Questions fréquentes
Quelque chose est-il envoyé à un serveur ?
Non. Cet outil porte la mention « client » : l'aperçu, c'est votre propre navigateur qui rend le CSS, et la règle générée est assemblée à partir des valeurs des curseurs dans la page. Rien n'est transmis.
Quelle différence entre box-shadow et filter: drop-shadow ?
box-shadow suit la boîte de l'élément — un rectangle, ou un rectangle arrondi si vous avez un border-radius. filter: drop-shadow suit la forme réellement visible, transparence comprise. Pour un PNG avec un logo détouré ou un SVG irrégulier, box-shadow dessine donc l'ombre du rectangle autour, ce qui rend mal, tandis que drop-shadow épouse le contour, ce qui rend bien. Pour des cartes rectangulaires ordinaires, box-shadow coûte moins cher et fait le même travail.
Pourquoi mon ombre inset n'apparaît-elle pas ?
Généralement parce que l'élément a un fond peint par-dessus, ou parce qu'il n'a pour ainsi dire pas de taille. Une ombre inset est dessinée à l'intérieur de la boîte de remplissage, au-dessus du fond mais sous le contenu — si l'élément est vide et sans hauteur, il n'y a rien sur quoi dessiner. Vérifiez aussi que vous ne l'avez pas posée sur un élément dont l'intérieur est entièrement recouvert par un enfant.
Une ombre peut-elle suivre un border-radius ?
Oui, automatiquement. box-shadow utilise la forme de la boîte de bordure : un élément arrondi obtient donc une ombre arrondie sans travail supplémentaire. C'est l'une des raisons pour lesquelles box-shadow est préférable à une image d'ombre dessinée à la main — elle reste correcte quand le rayon change.
Comment faire une ombre d'un seul côté ?
Décalez-la plus que vous ne la floutez, et rentrez les côtés avec un étalement négatif. Quelque chose comme 0 8px 6px -6px black produit une ombre qui n'apparaît que sous l'élément : l'étalement négatif la rétrécit plus étroite que la boîte, le décalage la pousse vers le bas, et le flou adoucit ce qui reste. Tenter la chose avec un simple décalage et sans étalement négatif laissera toujours l'ombre dépasser sur les côtés.