J'ai passé une quarantaine de minutes une fois à essayer de faire correspondre une ombre d'un fichier Figma Le concepteur m'avait donné une couleur, un décalage X et Y, un flou, et un spread, qui est tout ce dont vous avez besoin, et je n'arrivais toujours pas à le faire bien L'ombre dans le navigateur était plus lourde et plus plate que la maquette, et je n'arrêtais pas de pousser le rayon de flou de haut en bas comme ça le réparerait.
Ce ne serait pas le cas, car la maquette avait deux ombres empilées Une sombre serrée pour le contact, une large douce pour la lumière ambiante Figma les a montrées comme des couches séparées dans un panneau que j'avais effondré Une fois que je les ai écrites comme une paire séparée par des virgules le match était instantané.
C'est le truc avec les propriétés CSS dans ce guide Aucun d'entre eux n'est compliqué Tous ont un ou deux comportements qui ne sont pas évidents à partir de la syntaxe, et vous pouvez perdre un après-midi à l'un d'entre eux Ce guide est ces comportements, écrits.
Chaque générateur lié ici s'exécute dans votre navigateur, met à jour un aperçu en direct pendant que vous faites glisser et vous remet le CSS. Je les construis à [Toolz.dev](/et les utilise constamment, principalement parce que lire un raccourci de quatre valeurs est plus difficile que de regarder un rectangle.
tl;dr : manier Ombre de boîte pour la profondeur, Ombre de texte pour la lueur et les contours, Rayon Frontière pour les coins y compris les elliptiques, Filtres CSS pour les effets de flou, de luminosité et de couleur, Glassmorphisme pour panneaux dépoli, Neumorphisme pour les surfaces surélevées souples, Dégradés pour les arrière-plans, et le Convertisseur d'unités CSS quand vous avez besoin de px in rem Tous courent côté client avec un aperçu en direct Les deux règles qui valent la peine d'être transportées : les ombres réelles sont superposées, et
backdrop-filteril a besoin de quelque chose derrière pour s'estomper.
De quel générateur ai-je besoin ?
| tu veux | Propriété | outil |
|---|---|---|
| Une carte qui se lève de la page | box-shadow |
Ombre de boîte |
| Texte lumineux, esquissé ou en relief | text-shadow |
Ombre de texte |
| Coins arrondis ou en forme de pilule | border-radius |
Rayon Frontière |
| Flouter, atténuer, désaturer ou teinter un élément | filter |
Filtre CSS |
| Un panneau givré sur une photo | backdrop-filter |
Glassmorphisme |
| Un bouton souple qui regarde enfoncé dans la surface | superposé box-shadow |
Neumorphisme |
| Un fond de transition de couleur | linear-gradient |
Dégradé |
| Pour transformer 24 px en rem | aucun | Convertisseur d'unités |
Le reste de ce guide est ce que chacun fait et où il mord.
Comment fonctionne le box-shadow ?
Le raccourci est composé de cinq valeurs et d'une couleur :
box-shadow: 0 4px 12px 0 rgb(0 0 0 / 0.15);
/* │ │ │ │ └ colour */
/* │ │ │ └ spread: grow or shrink */
/* │ │ └ blur: 0 is a hard edge */
/* │ └ vertical offset */
/* └ horizontal offset */
Les décalages déplacent l'ombre Le flou adoucit son bord, l'étalant vers l'extérieur d'environ la moitié de la valeur du flou dans chaque direction Le spread fait croître ou rétrécit l'ombre avant que le flou ne soit appliqué, et un spread négatif est l'astuce d'une ombre qui se trouve repliée sous un élément plutôt que de la halo.
La partie qui manque aux gens : la pile d'ombres. Une liste séparée par des virgules rend l'arrière vers l'avant, la première ombre sur le dessus :
box-shadow:
0 1px 2px rgb(0 0 0 / 0.20), /* contact: tight, darker */
0 8px 24px rgb(0 0 0 / 0.12); /* ambient: wide, lighter */
Cette paire est la raison pour laquelle une ombre designer' ;s est meilleure que la vôtre Une ombre se lit comme un autocollant Deux se lit comme un objet avec un poids Le Générateur d'ombre de boîte vous permet d'ajouter des calques et de faire glisser chacun d'eux séparément, ce qui est le seul moyen judicieux de les régler.
inset déplace l'ombre à l'intérieur de la boîte de bordure, c'est ainsi que vous obtenez une entrée qui semble en retrait, ou la moitié interne d'une surface neumorphe.
Une note de performance qui m'a mordu sur de vrais projets : animer box-shadow force une repeinture à chaque image Si vous voulez qu'une carte se soulève en vol stationnaire, animez transform et croiser un deuxième élément qui tient la plus grande ombre Le référence MDN box-shadow documente la syntaxe dans son intégralité.
À quoi sert l’ombre textuelle, à part les ombres portées ?
Même idée, une valeur de moins. text-shadow n'a pas de propagation:
text-shadow: 1px 1px 2px rgb(0 0 0 / 0.5);
Ses utilisations intéressantes ne sont pas du tout des ombres.
Esquisses. Quatre ombres dures à flou nul, une par diagonale, faux un trait autour du texte Il est plus lourd que -webkit-text-stroke mais cela fonctionne partout et cela sort du glyphe plutôt que de diviser la différence :
text-shadow: 1px 1px 0 #000, -1px 1px 0 #000,
1px -1px 0 #000, -1px -1px 0 #000;
Lueur. Zéro décalage, grand flou, couleur saturée, répété deux ou trois fois pour créer de l'intensité.
Lisibilité sur les images. Une seule ombre sombre douce sous texte blanc vous achète du contraste lorsque l'arrière-plan est une photo que vous ne contrôlez pas Ce n'est pas un substitut à un scrim approprié, et il ne sauvera pas un rapport de contraste défaillant, mais il empêche les descendeurs de disparaître dans une tache brillante.
Construisez les trois sur le Générateur d'ombres textuelles. Si vous recherchez une exigence de contraste plutôt qu'un effet, vérifiez le résultat par rapport à WCAG avec le Vérificateur de contraste de couleurs au lieu de le regarder.
Pourquoi le rayon frontière prend-il huit valeurs ?
La plupart des gens en utilisent un. La forme complète est composée de deux groupes de quatre, séparés par une barre oblique :
border-radius: 20px 40px 60px 80px / 40px 20px 80px 60px;
/* ─────horizontal──── ──────vertical───── */
Avant la barre oblique : le rayon horizontal de chaque coin, dans le sens des aiguilles d'une montre à partir du haut à gauche Après : le rayon vertical Donnez les deux et chaque coin devient une ellipse plutôt qu'un quart de cercle C'est ainsi que vous obtenez des formes de blob organiques sans SVG.
Deux comportements à connaître.
Les pourcentages se résolvent par rapport à différents axes. Un rayon horizontal en % est un pourcentage de l'élément' ; s largeur, celui vertical de sa hauteur Donc border-radius: 50% sur un rectangle donne une ellipse, pas un rectangle arrondi, ce qui surprend les gens la première fois.
Le navigateur réduit les rayons lorsqu'ils se chevauchent. Si deux rayons adjacents totalisent plus que le côté qu'ils partagent, tous les rayons sont réduits proportionnellement jusqu'à ce qu'ils s'ajustent Vous ne pouvez pas déborder la forme, c'est pourquoi border-radius: 9999px produit une pilule de manière fiable.
le Générateur de rayon frontalier expose les huit valeurs avec des curseurs par coin et émet le raccourci valide le plus court, ce qui vaut la peine d'être obtenu car écrire la forme slash à la main est vraiment désagréable.
Que peuvent faire les filtres CSS, et que coûtent-ils ?
filter applique les opérations graphiques à un élément et à tout ce qu'il contient :
filter: blur(4px) brightness(1.1) saturate(1.2);
Les fonctions composent de gauche à droite, et l'ordre change le résultat Le flou puis l'éclaircissement n'est pas la même chose que l'éclaircissement puis le flou.
| Fonction | Fait | Surveiller |
|---|---|---|
blur() |
Flou gaussien | Cher à grands rayons ; brouille les bords vers l’extérieur |
brightness() |
Multiplie la légèreté | Au-dessus de 1 clips surlignote en blanc |
contrast() |
Pousse les valeurs du gris moyen | Les concassements se détaillent rapidement |
grayscale() |
Supprime la saturation | Moins cher qu'un actif en double |
sepia() |
Carte de tonalité chaude | Combiner avec hue-rotate() pour les autres teintes |
hue-rotate() |
Les changements se colorent selon un angle | Ne préserve pas la légèreté perçue |
drop-shadow() |
Ombre qui suit alpha | Contrairement à box-shadow: suit la forme réelle |
Cette dernière rangée est celle qui mérite d’être rappelée. box-shadow ombre la boîte frontière, donc un PNG transparent d'un logo obtient une ombre rectangulaire. filter: drop-shadow() trace le canal alpha et ombre le logo lui-même.
Le coût est réel Les filtres poussent un élément sur sa propre couche de compositing, et blur() en particulier est cher sur une grande surface Bien sur un bouton Réfléchissez deux fois sur une superposition pleine page sur un téléphone bas de gamme. MDN' ;s référence du filtre répertorie chaque fonction et son comportement d'interpolation.
Essayez des combinaisons sur le Générateur de filtres CSS(en), qui montre l'aperçu et la déclaration exacte côte à côte.
Comment construire un panneau de glassmorphisme qui fonctionne ?
Le verre dépoli est une propriété qui fait le travail :
background: rgb(255 255 255 / 0.15);
backdrop-filter: blur(12px) saturate(180%);
border: 1px solid rgb(255 255 255 / 0.25);
backdrop-filter filtre ce qui est derrière l'élément plutôt que l'élément lui-même Trois choses en découlent, et elles représentent presque chaque " ; pourquoi mon verre ressemble-t-il à une boîte grise" ; question.
Il a besoin de quelque chose derrière. Sur une couleur de fond plate, un fond flou est de la même couleur plate. L'effet n'existe que sur une photo, un dégradé ou un contenu superposé.
Le fond doit être translucide. Un fond entièrement opaque cache complètement le fond flou Quelque part entre 10 % et 25 % de blanc est la gamme habituelle.
La saturation est ce qui la vend. Le vrai verre concentre la couleur. saturate(180%) à côté du flou se trouve la différence entre un verre dépoli et une tache.
Ajoutez la bordure de la racine des cheveux car le verre a un bord et vérifiez le contraste avant l'expédition : le texte sur une photo floue passe ou échoue en fonction de la photo, et un panneau qui se lit parfaitement sur votre image de héros peut être illisible sur la suivante.
le Générateur de Glassmorphisme aperçus sur une image réelle, ce qui compte ici plus que pour tout autre effet dans ce guide.
Le neumorphisme vaut-il la peine d'être utilisé ?
Le neumorphisme, ou interface utilisateur douce, donne aux éléments un aspect extrudé de l'arrière-plan plutôt que de flotter au-dessus de lui. Deux ombres, coins opposés, une plus claire que la surface et une plus sombre :
background: #e0e5ec;
box-shadow: 8px 8px 16px #a3b1c6,
-8px -8px 16px #ffffff;
Échangez-les contre un état enfoncé ou utilisez-les inset sur les deux pour un look gravé.
La technique a une contrainte difficile : l'élément et son fond doivent être de la même couleur. L'effet est entièrement constitué des deux ombres, donc un bouton neumorphe sur un arrière-plan différent arrête la lecture comme extrudé et commence la lecture comme cassé.
Il a également un problème d'accessibilité qui mérite d'être honnête. L'ensemble de l'esthétique est peu contrasté par construction, et un bouton dont le seul affordance est une ombre douce peut échouer WCAG' ;s exigence de contraste non textuel pour les composants interactifs Si vous l'utilisez, donnez aux boutons une véritable bordure ou un style de mise au point qui ne dépend pas de l'ombre.
le Générateur de neumorphisme dérive les deux couleurs d’ombre de la couleur de votre surface, qui est la partie astucieuse à faire à la main.
Quand ai-je besoin d'un convertisseur d'unité ?
Plus souvent que vous ne le pensez, car les outils de conception parlent px et ce n’est souvent pas le cas d’un bon CSS.
rem est relatif à la taille de la police racine, donc une mise en page dans les échelles rem lorsqu'un utilisateur modifie son navigateur et sa taille de texte par défaut ; em est relatif au élément's taille de police, ce qui le rend utile pour un remplissage qui doit suivre son propre texte et dangereux lorsqu'il se complique à travers des éléments imbriqués.
L'arithmétique est triviale Le faire quarante fois en traduisant une spécification est l'endroit où les erreurs s'insinuent, surtout si la taille de la racine n'est pas de 16 px. Le Convertisseur d'unités CSS prend une racine configurable et affiche chaque unité à la fois.
Pour les pentes, le Générateur de gradient couvre les zones linéaires, radiales et coniques, et il y a une écriture plus longue dans le Guide de gradient CSS.
Les assembler : une carte, du début à la fin
Les propriétés sont rarement utilisées seules Voici une carte qui en utilise quatre, construite comme je le construirais.
Commencez par la forme et l'ombre au repos :
.card {
border-radius: 12px;
background: #fff;
box-shadow:
0 1px 2px rgb(0 0 0 / 0.06),
0 4px 12px rgb(0 0 0 / 0.08);
transition: transform 150ms ease, box-shadow 150ms ease;
}
Encore deux ombres, toutes deux légères Une carte de repos devrait à peine être levée Sauvegarder le drame pour l'état de vol stationnaire.
.card:hover {
transform: translateY(-2px);
box-shadow:
0 2px 4px rgb(0 0 0 / 0.08),
0 12px 28px rgb(0 0 0 / 0.12);
}
le translateY fait la plupart du travail perçu Le mouvement se lit comme soulevant de manière plus convaincante qu'une ombre plus grande, et il est bon marché parce que les transformées sont composées plutôt que repeintes.
Si la carte repose sur une photo au lieu d'une page plate, échangez le fond blanc contre du verre :
.card {
background: rgb(255 255 255 / 0.15);
backdrop-filter: blur(12px) saturate(180%);
border: 1px solid rgb(255 255 255 / 0.25);
}
Notez ce qui a changé et ce qui n'a pas changé Le rayon et les ombres se portent intacts Seul le traitement de surface diffère, ce qui est le modèle mental utile : la forme et la profondeur sont une décision, la surface en est une autre.
Qu'en est-il de la prise en charge des navigateurs et des fallbacks ?
La plupart de cela est vieux et sûr. box-shadow, text-shadow, border-radius et filter ont été soutenus partout pendant des années, et vous pouvez les écrire sans une seconde pensée.
backdrop-filter l'exception mérite-t-elle d'être gérée Le support est large maintenant, mais c'est la seule propriété ici qui produit un résultat véritablement cassé lorsqu'il manque : un panneau avec un fond blanc à 15 % et sans flou est un pâle frottis sur une photo Gardez-le :
.glass {
background: rgb(255 255 255 / 0.85); /* readable fallback */
}
@supports (backdrop-filter: blur(1px)) {
.glass {
background: rgb(255 255 255 / 0.15);
backdrop-filter: blur(12px) saturate(180%);
}
}
Le fallback est un panneau principalement opaque, ce qui n'est pas l'effet mais est parfaitement utilisable La version améliorée ne s'applique que là où le navigateur peut la livrer. MDN's @supports référence couvre la syntaxe, et il vaut la peine d'atteindre à tout moment une propriété avec un mode d'échec visuellement cassé plutôt qu'un mode simplement plus simple.
Comment puis-je maintenir la cohérence des effets dans un projet ?
Le mode d'échec sur une vraie base de code n'est pas une mauvaise ombre C'est quatorze ombres légèrement différentes, car tous ceux qui avaient besoin d'une carte ont écrit la leur.
Définissez-les une fois comme propriétés personnalisées et utilisez les noms :
:root {
--shadow-sm: 0 1px 2px rgb(0 0 0 / 0.06);
--shadow-md: 0 1px 2px rgb(0 0 0 / 0.06),
0 4px 12px rgb(0 0 0 / 0.08);
--shadow-lg: 0 2px 4px rgb(0 0 0 / 0.08),
0 12px 28px rgb(0 0 0 / 0.12);
--radius: 12px;
}
.card { border-radius: var(--radius); box-shadow: var(--shadow-md); }
.card:hover { box-shadow: var(--shadow-lg); }
Trois pas d'ombre suffisent généralement Si vous vous retrouvez à en ajouter un quatrième, c'est souvent parce qu'un composant a besoin d'un différent élévation plutôt qu'une ombre différente, et la réponse est de réutiliser une étape existante.
Cela rend également le mode sombre traitable Les ombres qui fonctionnent sur le blanc sont proches d'être invisibles sur une surface sombre, où la profondeur provient généralement d'une bordure plus claire ou d'une lueur subtile. Redéfinissez les jetons à l'intérieur d'une requête multimédia et chaque composant suit :
@media (prefers-color-scheme: dark) {
:root {
--shadow-md: 0 1px 2px rgb(0 0 0 / 0.4);
--shadow-lg: 0 8px 24px rgb(0 0 0 / 0.5);
}
}
Générez chaque valeur une fois avec les outils ci-dessus, collez-la dans le bloc de jetons et arrêtez d'y penser. C'est tout l'intérêt d'avoir un générateur : non pas pour écrire CSS, vous ne pouvez pas écrire à la main, mais pour arrêter de dépenser de l'attention sur des valeurs qui n'ont besoin de décider qu'une seule fois.
Où ces effets causent des problèmes d'accessibilité
Chaque propriété dans ce guide manipule le contraste, et le contraste est la chose dont les exigences d'accessibilité sont principalement au sujet de Quatre pièges spécifiques.
Les composants interactifs ont besoin de limites visibles. WCAG 2.2 nécessite un contraste de 3 :1 pour les parties d'un contrôle qui l'identifient Un bouton dont le seul bord est une ombre douce peut échouer cela, qui est le problème structurel avec le neumorphisme et la raison pour laquelle une bordure ou un anneau de focalisation solide n'y est pas facultatif.
Les panneaux de verre héritent de leur arrière-plan et de leur problème de contraste n°39. Le texte sur un panneau dépoli est lisible ou non selon la photo derrière, et la photo change souvent Testez par rapport à votre pire image, pas votre héros Lever le panneau' ; l'opacité de l'arrière-plan est généralement une meilleure solution que de rendre le texte plus audacieux.
Les filtres changent de contraste silencieusement. brightness() et contrast() appliqué à un contenant s'applique également au texte qui s'y trouve A filter: brightness(1.15) sur une carte pour la faire éclater peut tranquillement pousser votre corps de texte sous le seuil de 4.5 :1 Vérifiez après avec le Vérificateur de contraste de couleurs', pas avant.
Ne laissez pas une ombre être le seul indicateur d'état. Si le vol stationnaire, la mise au point et l'appui ne diffèrent que par la profondeur de l'ombre, les utilisateurs de clavier et toute personne ayant une vision basse perdent la distinction Associez le changement d'ombre à une transformation, un contour ou un changement de couleur.
Rien de tout cela ne rend les effets inutilisables Cela en fait des choses à vérifier plutôt qu'à supposer, ce qui prend environ une minute par composant avec un vérificateur de contraste ouvert.
Ces outils envoient-ils mon travail n'importe où ?
Non. Chaque générateur ici fonctionne entièrement dans le navigateur Il n'y a pas d'étape de téléchargement ni d'aller-retour sur le serveur, c'est pourquoi ils répondent instantanément lorsque vous faites glisser un curseur C'est la même raison pour laquelle le reste du catalogue fonctionne hors ligne, couvert dans le Guide de confidentialité des données.
Erreurs courantes
- Une ombre au lieu de deux. La différence la plus visible entre une ombre manuscrite et une ombre conçue.
- Animation
box-shadowen vol stationnaire. Repeint chaque cadre. Animertransformet le fondu enchaîné à la place. backdrop-filtersur une couleur unie. Rien à brouiller, donc rien ne se passe.- Fond opaque sur un panneau de verre. Cache l'effet que vous venez d'écrire.
- Neumorphisme sur un fond dépareillé. L'illusion dépend de leur identité.
border-radius: 50%en attendant un rectangle arrondi. Sur un élément non carré, vous obtenez une ellipse.- Expédition de n'importe lequel de ceux-ci sans contrôle de contraste. Les ombres et le verre réduisent tous deux le contraste, et les deux sont faciles à régler de manière excessive sur un bon moniteur.



