CSS Variables
Tout le thème tient dans six propriétés personnalisées (--bg, --card-bg, --card-border, --text, --text-muted, --accent) que la classe .active redéfinit d'un coup ; chaque couleur qui les lit glisse vers la nouvelle valeur en 0,6 s. Une classe à poser, aucune règle par élément à dupliquer ; 150 ms si l'utilisateur réduit les animations.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Transitions comprend 52 effets, dont 9 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
La scène .th-morph-scene (300 × 220 px, coins de 16 px) déclare six propriétés personnalisées : --bg: #0f172a, --card-bg (blanc à 5 %), --card-border (blanc à 8 %), --text: #fff, --text-muted (blanc à 50 %) et --accent: #8b5cf6. Tout le reste les lit : le fond de la scène (background: var(--bg)), le titre et la phrase, la carte intérieure (fond et bordure), le carré d'accent et son libellé. La règle .th-morph-scene.active redéfinit les six d'un bloc (#f1f5f9, blanc, #e2e8f0, #0f172a, #64748b, #6366f1) : changer de thème revient à poser une classe sur un seul élément, les enfants héritent des nouvelles valeurs.
Une propriété personnalisée non déclarée ne s'anime pas : le navigateur ne sait pas que --bg est une couleur et la remplace d'un coup. Ce sont donc les propriétés qui la consomment qui portent la transition : background-color .6s sur la scène et le carré, background-color .6s, border-color .6s sur la carte, color .6s sur les trois textes. Quand --bg change, la valeur calculée de background-color change, et c'est elle qui est interpolée. Mesuré 300 ms après le clic : fond de scène rgb(196, 201, 208) dans Chromium 151, rgb(190, 195, 202) dans Firefox 153, rgb(194, 199, 206) dans WebKit 26, puis #f1f5f9 exact à 1,5 s ; le retour suit le même chemin. Les transitions sont listées propriété par propriété, jamais all : si vous changez la taille de la carte, elle ne s'animera pas par accident.
Le script (0,6 Ko) arme chaque .th-morph-scene déclarée role="button" : clic, Entrée et Espace basculent .active et aria-pressed. Une scène sans ce rôle n'est pas touchée, et c'est le cas d'usage réel : la classe est posée par votre propre contrôle (un sélecteur d'établissement, une heure de garde), et tous les composants placés dans la scène suivent, à condition que chaque propriété qui lit une variable porte sa transition. Le jeu de variables s'étend librement : ajoutez --ok ou --warn pour des couleurs d'état, elles basculeront avec les autres. L'effet ne lit pas prefers-color-scheme et ne mémorise rien.
Accessibilité
- Clavier et rôle : la scène de démonstration est un
role="button"focalisable, nommé « Thème clair », avecaria-pressed. Mesuré : atteinte à la touche Tab dans Chromium et WebKit, basculée par Entrée et Espace dans les trois moteurs, contour violet au focus clavier. En production, pilotez la classe depuis un vrai bouton ou un sélecteur, comme dans les exemples. - Mouvement réduit : rien ne se déplace, seules des couleurs changent ; sous
prefers-reduced-motion: reduce, la durée tombe à 150 ms. Mesuré : à 60 ms, le fond est déjà àrgb(166, 171, 180)dans Chromium, puis final à 300 ms. - Contraste : phrase secondaire à 5,2:1 sur le sombre et 4,3:1 sur le clair (
#64748bsur#f1f5f9) : passez-la à#5b6678si elle porte une information importante. Pendant les 0,6 s, texte et fond passent ensemble par des gris moyens : ne déclenchez pas la bascule pendant une saisie.
Compatibilité navigateur
CSS (propriétés personnalisées, transitions de couleur) + 0,6 Ko de JavaScript, aucune dépendance. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : mêmes couleurs intermédiaires à quelques unités près, même retour, mêmes touches. Les propriétés personnalisées existent depuis Chrome 49, Firefox 31 et Safari 9.1. L'effet n'utilise pas @property : il marche donc aussi dans les navigateurs qui ne savent pas animer une variable. Le plancher vient de gap dans des boîtes flex : Chrome et Edge 84, Firefox 63, Safari 14.1 (iOS 14.5) ; avant, les éléments se touchent.
Un navigateur sans propriétés personnalisées ignore les déclarations en var() : la scène perd ses couleurs (fond transparent, texte par défaut). Ajoutez une couleur fixe avant chaque var() si vous visez un navigateur aussi ancien. Sans JavaScript, la scène reste dans son thème de départ ; poser active dans le HTML sert directement le second.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec Premium) :
<div class="th-morph-root">
<div class="th-morph-scene" role="button" tabindex="0" aria-pressed="false" aria-label="Thème clair">
<h3>…</h3>
<p>…</p>
<div class="th-morph-card">
<div class="th-morph-dot"></div>
<span>…</span>
</div>
</div>
</div>
Le code complet HTML + CSS + JS de CSS Variables, prêt à coller — et les 840 effets. Ou 299 € TTC une fois, accès à vie.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Les deux jeux de variables (CSS — .th-morph-scene et .th-morph-scene.active) |
6 variables, sombre puis clair | Changez les valeurs, pas les règles : tout ce qui lit une variable suit. Ajoutez-en autant qu'il faut (--ok, --danger), en les déclarant dans les deux jeux. |
Durée (CSS — .6s sur chaque transition) |
0,6 s | Toutes les durées doivent rester égales, sinon le texte arrive avant son fond. 0,3 s pour un changement vif, 1 s pour une ambiance. |
Nouveaux composants (CSS — leur propre transition) |
seuls les éléments de la démo transitionnent | Un élément ajouté qui lit var(--accent) change de couleur, mais d'un coup s'il ne déclare pas transition: background-color .6s (ou color, border-color, fill). |
Déclencheur (HTML — role="button" sur la scène) |
la scène entière est le bouton | Retirez role, tabindex et aria-pressed et posez .active depuis votre contrôle : le script ne touche plus la scène. |
Mouvement réduit (CSS — transition-duration: .15s) |
150 ms | Mettez 0s pour un changement instantané. |
FAQ
@property --bg { syntax: '<color>'; inherits: true; initial-value: #0f172a; } puis transition: --bg .6s sur la scène : le navigateur sait alors que --bg est une couleur et l'interpole, et les enfants n'ont plus besoin de leur propre transition (mesuré dans Chromium 151, Firefox 153 et WebKit 26). Mais chaque variable doit être déclarée ainsi, et @property n'existe que depuis Chrome 85, Safari 16.4 et Firefox 128 : sans lui, la couleur saute. Les transitions posées sur les propriétés consommatrices marchent partout ; c'est le choix fait ici.prefers-color-scheme et n'enregistre rien. Les variables s'y prêtent bien : un bloc @media (prefers-color-scheme: light) { .th-morph-scene { … le jeu clair … } } sert le bon thème sans JavaScript ; pour retenir un choix contraire, écrivez-le dans localStorage et posez la classe au chargement, avant le premier affichage, sinon la transition se joue à l'ouverture..active par pièce de la carte (fond, avatar, nom, texte, deux boutons) : c'est explicite et autonome, mais chaque nouvelle pièce demande sa paire de règles. CSS Variables écrit un seul jeu de valeurs que tout le composant lit : ajouter un élément ne demande qu'une transition. Choisissez CSS Variables pour un thème qui couvre plusieurs composants ou plusieurs marques, Card Theme pour un widget isolé qui ne doit rien partager avec la page.