Une carte qui semble flotter légèrement au-dessus de la page, un bouton qui gagne en épaisseur au survol, une fenêtre modale clairement détachée du contenu derrière elle : box-shadow est la propriété qui donne du relief à une interface plate, sans ajouter la moindre image ni la moindre balise supplémentaire.
Sa syntaxe tient en une ligne, mais cache plusieurs subtilités : l'ordre exact des valeurs, le mot-clé inset qui inverse tout, et la possibilité d'empiler plusieurs ombres sur un seul élément.
Définition
box-shadow projette une ombre autour de la boîte d'un élément, en suivant sa forme, y compris ses angles arrondis par border-radius. Seules deux valeurs sont obligatoires, le décalage horizontal et vertical ; blur, spread et couleur restent facultatifs.
.carte {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}Aucun décalage horizontal, quatre pixels vers le bas, un flou de douze pixels, et une couleur noire à 15% d'opacité : une ombre douce et discrète, la plus courante sur une carte d'interface.
Les cinq valeurs, une par une
| Valeur | Rôle | Obligatoire ? |
|---|---|---|
offset-x | Décalage horizontal, positif vers la droite | Oui |
offset-y | Décalage vertical, positif vers le bas | Oui |
blur-radius | Le flou appliqué aux bords de l'ombre | Non, 0 par défaut |
spread-radius | Agrandit ou réduit la forme de l'ombre | Non, 0 par défaut |
color | La couleur de l'ombre | Non, currentColor par défaut |
inset : l'ombre à l'intérieur
Ajouter le mot-clé inset avant les valeurs numériques fait basculer l'ombre à l'intérieur de la boîte plutôt qu'à l'extérieur, un effet utilisé pour simuler un champ de formulaire enfoncé ou un bouton pressé.
.champ-actif {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
}Empiler plusieurs ombres
box-shadow accepte une liste d'ombres séparées par des virgules. La première déclarée apparaît au-dessus des suivantes, ce qui permet de superposer une ombre nette et proche à une ombre large et diffuse, pour un rendu plus réaliste qu'une seule valeur.
Cette superposition rejoint la logique des systèmes de design qui définissent plusieurs niveaux d'élévation, du plus discret au plus prononcé, chacun associé à une paire de valeurs déjà calculée plutôt qu'improvisée à chaque nouveau composant.
.carte-elevee {
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.08),
0 8px 24px rgba(0, 0, 0, 0.12);
}Une box-shadow ne modifie jamais la taille de la boîte au sens du Modèle de boîte : elle ne pousse aucun élément voisin, ne déclenche aucune barre de défilement. En contrepartie, un parent avec overflow: hidden coupe l'ombre exactement comme il couperait tout autre contenu qui déborde.
box-shadow ou filter: drop-shadow, lequel choisir
Les deux propriétés produisent une ombre, mais pas de la même forme. box-shadow dessine toujours un rectangle, ou la forme arrondie imposée par border-radius : sur une image au fond transparent, elle projette donc l'ombre d'un carré, pas celle du logo lui-même.
filter (CSS) avec drop-shadow suit au contraire les pixels réellement opaques de l'élément, ce qui la rend indispensable sur un logo ou une icône détourée, là où box-shadow donnerait un résultat visiblement faux.
Le filtre a aussi un coût de performance plus élevé sur une grande surface, puisqu'il retraite l'ensemble des pixels de l'élément à chaque image, alors que box-shadow reste une simple couche ajoutée au rendu final.
Questions fréquentes
Peut-on animer box-shadow avec une transition ?
Oui, mais avec prudence : recalculer une ombre floue à chaque image d'une animation coûte plus cher au navigateur qu'une transition sur transform ou opacity. Pour un effet de survol fréquent, mieux vaut transformer une ombre déjà présente en une ombre plus marquée plutôt que de la faire apparaître depuis rien.
À quoi sert la valeur de spread négative ?
Une valeur négative réduit la taille de la forme projetée avant d'appliquer le flou, utile pour créer une ombre plus concentrée qu'une bordure classique, par exemple pour simuler un anneau de focus fin autour d'un champ.
Pourquoi mon ombre est-elle coupée sur un des côtés ?
Le plus souvent parce qu'un parent porte overflow: hidden ou overflow: auto, qui coupe toute ombre dépassant de ses propres limites exactement comme il couperait un texte ou une image qui déborde.