Depuis plusieurs années, le CSS ne cesse d’évoluer. D’un simple langage de style, il est devenu un outil puissant capable de gérer des transitions, des animations, et même des comportements autrefois réservés au JavaScript. Aujourd’hui, trois nouveautés majeures viennent transformer encore un peu plus la manière dont vous concevez vos interfaces : @property
, le type safety (ou sécurité de typage), et les animations déclaratives.
Ces nouvelles fonctionnalités font partie d’une volonté globale du W3C : rendre le CSS plus expressif, plus performant et plus sûr. Avec elles, les développeurs peuvent désormais créer des variables CSS animables, garantir leur cohérence grâce au typage, et définir des animations fluides et naturelles sans une seule ligne de JavaScript.
Si vous avez déjà rencontré des difficultés à animer une couleur ou une valeur définie dans une variable CSS, ou si vous avez constaté des comportements étranges lors de transitions, ces nouveautés vont littéralement changer votre manière de coder. Elles permettent d’éviter des bugs subtils, d’améliorer les performances du rendu et surtout, d’alléger considérablement le code.
Dans ce tutoriel, vous allez découvrir pas à pas comment utiliser ces nouveautés. Vous apprendrez à créer vos propres propriétés CSS typées, à comprendre comment le navigateur interprète les types de valeurs, et à réaliser des animations modernes, puissantes et déclaratives, sans dépendre de JavaScript.
Nous aborderons ensemble les bases, les exemples pratiques, et même un cas d’usage complet pour bien ancrer ces connaissances. Mais avant d’entrer dans le concret, prenons le temps de comprendre pourquoi ces nouveautés sont apparues et quels problèmes elles résolvent.
- Comprendre le contexte : pourquoi ces nouveautés CSS ?
- La règle @property : une révolution silencieuse
- Comprendre la "type safety" en CSS
- Les animations déclaratives : moins de JavaScript, plus de CSS
- Optimisation et compatibilité
- Étude de cas complète : créer un bouton dynamique 100 % CSS
- Objectif : un bouton qui réagit avec fluidité
- Préparation de la base HTML et CSS
- Déclaration des propriétés personnalisées typées
- Application des variables et transitions
- Création des interactions : survol et clic
- Animation continue de la lueur
- Gestion du mode réduit (accessibilité)
- Résultat final et explication détaillée
- le CSS moderne, plus intelligent que jamais
Comprendre le contexte : pourquoi ces nouveautés CSS ?
Le CSS n’a jamais cessé de progresser. Cependant, certaines limitations persistent depuis longtemps, notamment autour des variables CSS et des animations. Pour saisir l’intérêt de @property
et de la sécurité de typage, il faut d’abord revenir sur ces limites historiques.
Les limites des variables CSS traditionnelles
Lorsque les variables CSS personnalisées (les fameuses --ma-variable
) ont été introduites, elles ont représenté une avancée énorme. Elles ont permis de mutualiser les valeurs, d’éviter la duplication, et d’introduire une logique plus cohérente dans le code. Vous pouviez écrire :
:root {
--couleur-principale: #3498db;
}
et l’utiliser partout :
button {
background-color: var(--couleur-principale);
}
Simple, efficace et puissant.
Mais très vite, une limite est apparue : ces variables ne sont pas typées. Pour le navigateur, --couleur-principale
n’est qu’une simple chaîne de caractères. Cela signifie que le navigateur ne sait pas ce que contient la variable, ni comment l’animer correctement.
Si vous tentiez d’animer une variable contenant une couleur ou une valeur numérique, vous pouviez rencontrer un problème : l’animation ne fonctionnait pas. Le navigateur ne savait pas interpoler les valeurs, car il ne connaissait pas leur type.
Prenons un exemple concret :
:root {
--couleur-fond: #ff0000;
}
div {
background-color: var(--couleur-fond);
transition: background-color 1s;
}
div:hover {
--couleur-fond: #0000ff;
}
Vous pourriez penser que la couleur va passer du rouge au bleu en douceur.
Mais non : sans typage, la transition est ignorée. La couleur change brutalement, car le navigateur ne comprend pas comment interpoler deux chaînes de texte.
C’est ici qu’intervient la première nouveauté : la règle @property
.
Les problèmes de performance et de fluidité dans les animations
Un autre problème récurrent concerne la fluidité des animations CSS.
Lorsqu’une animation dépend d’une variable non typée, le moteur CSS doit recalculer des styles complets à chaque image. Cela peut causer des ralentissements visibles, surtout sur des interfaces riches ou sur mobile.
Les développeurs contournaient ce problème en utilisant du JavaScript, via les API requestAnimationFrame()
ou des bibliothèques comme GSAP. Mais cela introduit une autre difficulté : plus de code, plus de dépendances, et plus de risques d’incohérence.
Avec les nouveautés CSS, notamment @property
, le navigateur sait comment animer une valeur sans passer par le JavaScript. Les calculs sont faits au niveau du moteur de rendu, directement dans le pipeline graphique, ce qui améliore la fluidité et les performances.
Le besoin d’un contrôle typé et de comportements cohérents
Sans typage, les variables CSS sont très flexibles, mais aussi très fragiles.
Rien n’empêche un développeur d’écrire :
--largeur: 100px;
--largeur: rouge;
Le navigateur acceptera les deux lignes sans broncher.
Mais lorsque vous essaierez d’utiliser cette variable dans une propriété comme width
, le comportement deviendra imprévisible.
C’est pour éviter ce genre de situation que la type safety a été introduite.
Grâce à elle, le navigateur sait que --largeur
doit toujours être une longueur (par exemple, en px
, em
, %
, etc.) et qu’une autre valeur, comme une couleur, sera considérée comme invalide.
Cette sécurité de typage améliore la prévisibilité du code et permet de détecter des erreurs avant même qu’elles n’affectent le rendu.
En outre, le typage rend possible une autre évolution majeure : l’animation déclarative.
En connaissant le type exact d’une valeur, le moteur CSS peut interpoler entre deux états, par exemple entre 10px
et 50px
, ou entre deux couleurs, sans intervention externe.
Un pas vers des animations purement déclaratives
Jusqu’à récemment, animer une variable CSS nécessitait une astuce ou du JavaScript. Avec @property
, vous pouvez désormais déclarer explicitement une variable, préciser son type (<color>
, <length>
, <number>
, etc.), et même définir une valeur initiale.
Cette approche ouvre la porte à des animations 100 % CSS, plus simples à écrire, plus performantes et plus faciles à maintenir.
Imaginez pouvoir animer une variable représentant la teinte d’un dégradé, ou la position d’un élément, simplement avec une règle CSS.
C’est désormais possible, et vous allez le découvrir dans la suite de ce tutoriel.
Une compatibilité en pleine expansion
Ces nouveautés ne sont plus expérimentales.
La règle @property
est déjà prise en charge par la plupart des navigateurs modernes : Chrome, Edge et Safari l’intègrent, tandis que Firefox est en cours d’implémentation.Il est donc temps de s’y intéresser sérieusement.
Et même si vous devez gérer la compatibilité avec des versions plus anciennes, des solutions de graceful degradation existent : votre site continuera de fonctionner, simplement sans profiter de ces nouvelles optimisations.
La règle @property : une révolution silencieuse
Parmi toutes les nouveautés récentes du langage CSS, la règle @property
est sans doute l’une des plus discrètes, mais aussi l’une des plus puissantes.
Elle vous permet de déclarer des propriétés CSS personnalisées typées, avec une valeur initiale et un comportement d’héritage défini. Autrement dit, elle apporte au CSS une véritable forme de “programmation déclarative”, où vous pouvez contrôler finement la nature et le comportement de vos variables.
Avant son apparition, les variables CSS étaient de simples chaînes de caractères.
Désormais, grâce à @property
, elles deviennent de vraies propriétés CSS dynamiques, compréhensibles par le navigateur, et donc animables, validées et cohérentes.
Comprendre ce que fait réellement @property
La règle @property
agit comme une sorte de “contrat” passé avec le navigateur.
Elle lui dit :
« Je vais créer une variable personnalisée, et je veux que tu saches quel type de valeur elle contient, si elle s’hérite ou non, et quelle est sa valeur par défaut. »
Autrement dit, @property
permet de déclarer officiellement une variable CSS dans le langage, au lieu de simplement l’utiliser de manière implicite.
Prenons un exemple simple :
@property --rotation {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
Ici, vous indiquez au navigateur que :
--rotation
est une propriété personnalisée (une variable CSS),- elle contiendra toujours une valeur de type angle (par exemple
30deg
,45deg
, etc.), - elle n’est pas héritée par les éléments enfants,
- et sa valeur initiale est
0deg
.
Cette seule déclaration change tout.
Grâce à cette définition claire, le moteur CSS sait comment interpoler la valeur d’un angle lors d’une animation ou d’une transition.
Vous pouvez donc animer --rotation
sans recourir à du JavaScript ni à des astuces compliquées.
La syntaxe complète de @property
Une règle @property
se déclare toujours dans la feuille de style principale, comme une règle @keyframes
ou @media
.
Elle suit une syntaxe très stricte mais simple :
@property <nom-de-la-variable> {
syntax: <type>;
inherits: <true | false>;
initial-value: <valeur-par-défaut>;
}
Voyons chaque paramètre en détail :
syntax
Indique le type de valeur que la variable peut contenir.
Vous pouvez utiliser des types CSS comme :<color>
pour les couleurs (red
,#ff0000
,rgb(0,0,0)
),<length>
pour les longueurs (10px
,5em
),<number>
pour les nombres purs (1
,0.5
, etc.),<angle>
pour les rotations (30deg
,1turn
),<percentage>
pour les pourcentages (50%
),
ou encore<transform-function>
ou<time>
selon les besoins.
Si vous souhaitez accepter plusieurs types, vous pouvez les combiner à l’aide de la barre verticale :syntax: "<length> | <percentage>";
inherits
Définit si la propriété se transmet automatiquement aux éléments enfants.
La valeurtrue
signifie que l’enfant héritera de la variable définie par le parent.
La valeurfalse
empêche cette propagation.
En pratique, la plupart des variables animées sont définies avecinherits: false;
.initial-value
C’est la valeur utilisée par défaut lorsque la propriété n’est pas définie ailleurs.
C’est aussi la valeur à laquelle elle reviendra si elle est réinitialisée.
Elle doit correspondre au type défini danssyntax
.
Une fois que la propriété est déclarée, elle peut être utilisée comme n’importe quelle variable CSS, via var(--ma-variable)
.
Exemple concret : animer une rotation avec @property
Voyons maintenant un exemple concret pour comprendre comment cette règle s’intègre dans un scénario réel.
Imaginons que vous souhaitiez faire tourner un carré sur lui-même lorsque vous passez la souris dessus.
Avant, il fallait utiliser JavaScript ou des transformations CSS classiques.
Avec @property
, vous pouvez animer directement une variable d’angle.
Voici le code complet :
@property --rotation {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
.box {
width: 100px;
height: 100px;
background: royalblue;
transform: rotate(var(--rotation));
transition: --rotation 1s ease-in-out;
}
.box:hover {
--rotation: 360deg;
}
Explication :
- Vous déclarez d’abord la propriété personnalisée
--rotation
avec un type<angle>
.
Le navigateur sait donc comment interpoler cette valeur (par exemple de0deg
à360deg
). - Dans
.box
, la propriététransform
utilise la variable avecrotate(var(--rotation))
. - La transition
--rotation 1s ease-in-out
indique que tout changement de valeur sur cette variable doit être animé pendant une seconde. - Au survol (
:hover
), la variable--rotation
prend la valeur360deg
.
Le navigateur anime alors automatiquement cette transition.
Résultat : un carré qui tourne en douceur, sans JavaScript, sans hack, et avec un rendu parfaitement fluide.
Passez votre souris
Comparaison avant / après @property
Avant l’introduction de @property
, ce même effet nécessitait souvent un contournement.
Les développeurs animaient directement transform: rotate()
ou utilisaient une variable non typée, mais cela ne fonctionnait pas toujours de manière fluide.
Voici la différence :
Avant :
:root {
--rotation: 0deg;
}
.box {
transform: rotate(var(--rotation));
transition: transform 1s ease-in-out;
}
.box:hover {
--rotation: 360deg; /* Ne fonctionne pas avec transition */
}
Le problème est que la transition s’appliquait à transform
, pas à la variable.
Le navigateur ne savait pas animer la valeur contenue dans --rotation
.
Avec @property
:
La variable devient animable, et la transition peut s’appliquer directement à elle.
C’est plus propre, plus flexible et surtout, plus performant.
Animer des couleurs ou des longueurs
La même logique s’applique à tous les types de données.
Prenons l’exemple d’une animation de couleur :
@property --couleur-fond {
syntax: "<color>";
inherits: false;
initial-value: #ff0000;
}
div {
width: 150px;
height: 150px;
background-color: var(--couleur-fond);
transition: --couleur-fond 1s ease-in-out;
}
div:hover {
--couleur-fond: #0000ff;
}
Ici encore, la couleur passera du rouge au bleu avec une interpolation fluide.
Avant @property
, cette transition aurait été ignorée, car le navigateur ne savait pas comment animer la valeur d’une variable CSS non typée.
Vous pouvez également animer des longueurs :
@property --taille {
syntax: "<length>";
inherits: false;
initial-value: 50px;
}
.circle {
width: var(--taille);
height: var(--taille);
border-radius: 50%;
background: coral;
transition: --taille 0.5s ease;
}
.circle:hover {
--taille: 150px;
}
Au survol, le cercle grandit progressivement.
Le navigateur sait interpoler 50px
vers 150px
car la propriété est typée en <length>
.
Pourquoi @property change la donne
La force de @property
, c’est qu’elle combine la puissance des variables CSS avec la précision d’un typage fort.
Elle permet :
- d’éviter des incohérences dans les valeurs ;
- de faciliter l’animation de variables ;
- d’améliorer les performances des transitions, car tout est géré côté navigateur, sans recalculs inutiles.
Cette approche ouvre de nouvelles perspectives pour les thèmes dynamiques, les interfaces réactives, les modes jour/nuit, ou encore les animations complexes sans JavaScript.
Ce qu’il faut retenir avant d’aller plus loin :
@property
introduit un niveau de contrôle inédit dans le CSS.
Grâce à elle, vos variables ne sont plus de simples contenants, mais des entités logiques, cohérentes et animables.
Elles deviennent de véritables briques du langage, que le navigateur comprend, interprète et optimise.
Comprendre la « type safety » en CSS
Lorsqu’on parle de “type safety” ou de “sécurité de typage”, on pense souvent à des langages comme TypeScript, Java ou C#, mais rarement au CSS. Pourtant, avec l’arrivée de @property
, le CSS adopte lui aussi une forme de typage, bien que simplifiée.
Ce typage permet d’éviter des comportements inattendus, de renforcer la cohérence entre les propriétés, et de rendre le code plus prévisible. En d’autres termes, il rend votre CSS plus robuste et plus fiable, tout en offrant de nouvelles possibilités d’animation.
Qu’est-ce que le typage en CSS ?
Dans la plupart des langages informatiques, le typage désigne la capacité d’une variable à être associée à un type de donnée précis.
Par exemple, un entier (number
) ne peut pas être remplacé par une chaîne de caractères (string
). Si vous essayez, le compilateur ou le moteur d’exécution vous signale une erreur.
Jusqu’à récemment, le CSS ne proposait pas ce niveau de rigueur. Les variables définies avec la syntaxe --ma-variable
pouvaient contenir absolument n’importe quoi : un texte, une couleur, une longueur, voire une valeur incohérente.
Le navigateur ne validait rien. Il se contentait d’injecter la valeur telle quelle dans la propriété où elle était utilisée. Cela fonctionnait souvent, mais pouvait aussi produire des résultats incohérents ou imprévisibles.
Prenons un exemple concret :
:root {
--taille: 100px;
}
div {
width: var(--taille);
}
Ici, tout fonctionne.
Mais si quelqu’un écrit par erreur :
:root {
--taille: bleu;
}
Le navigateur ne protestera pas, mais la largeur de l’élément deviendra… inexistante.
En effet, “bleu” n’est pas une valeur valide pour la propriété width
.
Le code ne provoquera pas d’erreur visible, mais le rendu sera incorrect.
C’est ce type de problème que la sécurité de typage vient corriger.
Comment @property introduit le typage dans le CSS
Lorsque vous déclarez une propriété personnalisée avec @property
, vous devez préciser le type de valeur qu’elle accepte via le mot-clé syntax:
.
Cette indication donne au navigateur une compréhension sémantique de la variable : il sait ce qu’elle est censée contenir, et peut donc valider les valeurs attribuées.
Exemple :
@property --taille {
syntax: "<length>";
inherits: false;
initial-value: 100px;
}
Ici, vous informez explicitement le navigateur que la variable --taille
doit toujours contenir une longueur.
Dès lors :
- si vous lui donnez
200px
ou10em
, tout va bien ; - mais si vous essayez de lui attribuer
rouge
ou50%
, le navigateur considérera la valeur comme invalide.
Le grand avantage, c’est que cette validation est native, effectuée directement par le moteur CSS. Aucune extension, aucun script, aucune bibliothèque n’est nécessaire.
Les erreurs possibles sans typage
Sans typage, plusieurs erreurs subtiles peuvent se produire.
Voici quelques exemples classiques rencontrés dans les projets CSS :
- Erreurs d’unité :
:root { --marge: 50; } div { margin-top: var(--marge); }
Le navigateur interprète “50” comme une chaîne de caractères, pas comme une longueur.
Résultat : la propriété est ignorée. - Erreurs de type :
:root { --couleur: 20px; } p { color: var(--couleur); }
Là encore, pas d’erreur visible dans la console, mais le texte ne s’affichera pas dans la couleur attendue. - Erreurs d’interpolation :
Sans typage, les transitions entre deux valeurs deviennent impossibles à animer.
Le navigateur ne sait pas comment passer d’une chaîne à une autre, car il ignore leur nature (nombre, couleur, angle, etc.).
Grâce au typage introduit par @property
, tous ces problèmes disparaissent.
Le navigateur sait exactement comment manipuler la donnée et comment l’interpoler entre deux valeurs.
Exemples pratiques de typage CSS
Exemple 1 : Typage de couleur
@property --couleur-principale {
syntax: "<color>";
inherits: false;
initial-value: #ff0000;
}
.element {
background-color: var(--couleur-principale);
transition: --couleur-principale 1s;
}
.element:hover {
--couleur-principale: #0000ff;
}
Ici, la propriété --couleur-principale
est explicitement déclarée comme une couleur. Résultat : l’animation de la couleur est fluide et reconnue comme telle par le moteur CSS.
Exemple 2 : Typage de longueur
@property --taille {
syntax: "<length>";
inherits: false;
initial-value: 50px;
}
.cercle {
width: var(--taille);
height: var(--taille);
border-radius: 50%;
background: orange;
transition: --taille 0.5s ease;
}
.cercle:hover {
--taille: 120px;
}
Dans ce cas, le navigateur comprend qu’il doit interpoler entre deux valeurs numériques de longueur, et l’effet est d’une fluidité remarquable.
Exemple 3 : Typage d’angle
@property --rotation {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
.loader {
width: 60px;
height: 60px;
border: 4px solid lightgray;
border-top-color: steelblue;
border-radius: 50%;
animation: spin 1s linear infinite;
transform: rotate(var(--rotation));
}
@keyframes spin {
to {
--rotation: 360deg;
}
}
Ici, la propriété --rotation
permet d’animer directement un angle via les keyframes. Sans typage, une telle animation serait tout simplement impossible.
Les avantages concrets du typage CSS
L’ajout de la sécurité de typage dans le CSS apporte de nombreux bénéfices concrets, aussi bien en termes de maintenabilité que de performance.
- Moins d’erreurs silencieuses
Grâce au typage, le navigateur rejette automatiquement les valeurs incorrectes. Cela réduit les bugs subtils difficiles à diagnostiquer. - Animations plus fiables
Le moteur CSS peut interpoler correctement les valeurs, qu’il s’agisse de couleurs, de tailles ou d’angles. Les transitions deviennent plus naturelles. - Code plus clair et prévisible
En lisant la déclaration d’une propriété typée, un autre développeur comprend immédiatement le rôle et la nature de la variable. - Performances accrues
Les calculs sont effectués en interne, dans le moteur CSS, sans passer par le JavaScript. Cela réduit le coût de rendu et améliore la réactivité globale. - Interopérabilité avec d’autres fonctionnalités modernes
Le typage ouvre la voie à des combinaisons puissantes avec les animations déclaratives, les thèmes dynamiques, et les interfaces adaptatives.
Les bons réflexes à adopter
Pour tirer pleinement parti de la sécurité de typage, voici quelques réflexes à adopter dès maintenant dans vos feuilles de style :
- Toujours déclarer vos variables clés via
@property
.
Cela permet au navigateur de savoir comment les traiter et d’optimiser leur rendu. - Choisir le type le plus précis possible.
Par exemple, préférez<color>
à<string>
, ou<length>
à<number>
si la variable représente une taille.
Plus le type est précis, plus le moteur CSS peut l’interpréter efficacement. - Définir systématiquement une valeur initiale cohérente.
L’omission d’uneinitial-value
peut causer des comportements inattendus.
Cette valeur par défaut garantit la stabilité de votre interface. - Tester vos animations dans plusieurs navigateurs modernes.
Bien que@property
soit largement supporté, certains moteurs implémentent encore des subtilités dans la gestion des types.
Pourquoi la type safety prépare l’avenir du CSS
Cette évolution n’est pas anodine.
En introduisant la sécurité de typage, le CSS se rapproche des langages à typage fort, sans perdre sa simplicité.
Cela ouvre la porte à de futures innovations : propriétés complexes, comportements dynamiques, ou même validations avancées directement dans les navigateurs.
À terme, cette logique pourrait permettre d’éviter des milliers de lignes de JavaScript dans les applications web modernes.
Elle s’inscrit dans un mouvement plus large : le CSS devient un langage de logique déclarative complète, capable de gérer non seulement le style, mais aussi des interactions, des états et des comportements animés, de façon native.
Vous comprenez désormais comment le typage améliore la robustesse du CSS et prépare le terrain pour des animations plus intelligentes et performantes.
Les animations déclaratives : moins de JavaScript, plus de CSS
Depuis toujours, le CSS permet de créer des animations simples à l’aide des propriétés transition
et @keyframes
. Pourtant, dès qu’il s’agissait d’animer des éléments plus dynamiques ou des variables personnalisées, le recours à JavaScript devenait presque inévitable.

Des formations informatique pour tous !
Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…
Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.
Découvrez mes formations Qui suis-je ?Grâce à l’introduction de @property
, cette dépendance au script s’efface peu à peu au profit d’un modèle déclaratif, plus simple, plus lisible et surtout plus performant.
Cette nouvelle approche rend possible des animations avancées directement dans la feuille de style, tout en bénéficiant du moteur d’animation interne du navigateur, optimisé pour la fluidité et l’efficacité.
Retour sur les limites des animations classiques
Avant l’apparition de @property
, les variables CSS n’étaient pas animables. Même si vous pouviez modifier leur valeur à l’aide de JavaScript ou de classes CSS, le navigateur ne savait pas comment interpoler la transition entre deux états.
Prenons un exemple concret. Imaginons que vous vouliez animer la couleur d’un bouton via une variable CSS :
:root {
--couleur: #3498db;
}
button {
background-color: var(--couleur);
transition: background-color 1s;
}
button:hover {
--couleur: #e74c3c;
}
Dans cet exemple, même si la propriété background-color
est censée être animée, la transition ne se produit pas. Pourquoi ? Parce que la variable --couleur
change instantanément, et le navigateur ne la considère pas comme une propriété animable. Résultat : le bouton change de couleur sans effet de transition.
Ce comportement était frustrant, car les développeurs devaient alors contourner cette limitation avec du JavaScript, souvent en manipulant directement les valeurs RGB ou HSL, ou en forçant des re-rendus fréquents pour simuler une interpolation.
Mais ces solutions entraînaient souvent des problèmes de performances, notamment sur mobile, et compliquaient inutilement le code.
Comment @property
rend possible l’animation de variables CSS
C’est ici qu’intervient la règle @property
. En permettant de déclarer explicitement une variable CSS et son type, le navigateur est désormais capable d’interpréter correctement sa valeur, et donc de l’animer.
La syntaxe de base reste simple :
@property --couleur {
syntax: '<color>';
inherits: false;
initial-value: #3498db;
}
Cette déclaration indique que la variable --couleur
:
- est une couleur (
syntax: '<color>'
) ; - ne se transmet pas automatiquement aux enfants (
inherits: false
) ; - a une valeur initiale de
#3498db
.
Une fois cette variable déclarée, elle devient animable comme n’importe quelle propriété CSS.
Voici l’exemple précédent, mais cette fois avec @property
:
@property --couleur {
syntax: '<color>';
inherits: false;
initial-value: #3498db;
}
button {
background-color: var(--couleur);
transition: --couleur 1s;
}
button:hover {
--couleur: #e74c3c;
}
Cette fois, le changement de couleur se fait en douceur, exactement comme une transition native.
Le moteur CSS peut interpoler les deux couleurs car il connaît leur type et comprend comment passer progressivement de #3498db
à #e74c3c
.
Exemple : créer une animation fluide de gradient de fond
Prenons un cas un peu plus visuel pour bien saisir la puissance des animations déclaratives. Imaginons un fond dégradé animé qui change doucement de teinte.
Voici le code complet :
@property --angle {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
body {
--angle: 0deg;
background: linear-gradient(var(--angle), #ff7e5f, #feb47b);
transition: --angle 3s linear;
}
body:hover {
--angle: 360deg;
}
Explication :
- Nous déclarons une propriété personnalisée
--angle
de type<angle>
. - Le fond du
body
utilise cette variable pour définir l’orientation du dégradé. - Lorsqu’on survole la page, la variable passe de
0deg
à360deg
. - Grâce à la transition déclarative, le fond tourne de manière fluide, sans aucun JavaScript.
Ce genre d’animation était autrefois réservé aux bibliothèques JS comme GSAP ou anime.js. Désormais, quelques lignes de CSS suffisent pour obtenir un rendu fluide et natif.
Exemple avancé : animation de thème jour/nuit sans JavaScript
Passons maintenant à un exemple plus complet qui démontre l’intérêt des animations déclaratives pour des effets d’interface concrets.
Nous allons créer un thème jour/nuit qui change de couleur de fond et de luminosité à l’aide de @property
, sans une seule ligne de JavaScript.
@property --luminosite {
syntax: '<number>';
inherits: false;
initial-value: 1;
}
@property --fond {
syntax: '<color>';
inherits: false;
initial-value: #87ceeb;
}
body {
background-color: var(--fond);
filter: brightness(var(--luminosite));
transition: --fond 2s ease, --luminosite 2s ease;
}
body.nuit {
--fond: #2c3e50;
--luminosite: 0.5;
}
Ici :
- Nous définissons deux propriétés typées : une couleur (
--fond
) et un nombre (--luminosite
). - Le
body
applique ces variables au fond et à un filtre de luminosité. - En ajoutant ou retirant la classe
.nuit
(via un simple clic ou une media queryprefers-color-scheme
), le thème passe en mode sombre avec une transition fluide, sans script.
Cette approche ouvre la porte à des interfaces plus réactives, cohérentes et accessibles, tout en conservant la légèreté du CSS pur.
Cas d’usage réels : loaders, transitions de couleurs, micro-interactions
Les animations déclaratives ont de nombreuses applications concrètes dans les interfaces modernes.
Elles sont particulièrement utiles pour :
- Les loaders CSS : au lieu de manipuler des variables via JavaScript, vous pouvez faire tourner un indicateur de chargement ou changer ses couleurs en continu avec des
@keyframes
basés sur des variables typées. - Les transitions de thème : comme vu précédemment, changer les couleurs, ombres ou luminosités d’un site sans rechargement devient trivial.
- Les micro-interactions : par exemple, un bouton qui réagit subtilement à un clic ou un survol, avec des animations plus expressives et naturelles.
Voici un petit exemple de micro-interaction :
@property --scale {
syntax: '<number>';
inherits: false;
initial-value: 1;
}
button {
transform: scale(var(--scale));
transition: --scale 0.2s ease;
}
button:active {
--scale: 0.95;
}
Dès que l’utilisateur clique sur le bouton, celui-ci s’écrase légèrement, donnant un effet de pression.
Le tout, encore une fois, sans la moindre ligne de JavaScript.
Les navigateurs modernes gèrent ces animations directement dans le thread de composition, ce qui garantit une fluidité parfaite, même sur les appareils modestes.
Les animations déclaratives marquent un véritable tournant dans l’évolution du CSS. Elles offrent un équilibre idéal entre puissance et simplicité. En déclarant correctement vos variables avec @property
, vous pouvez :
- créer des transitions fluides sur n’importe quelle valeur personnalisée ;
- éliminer la dépendance au JavaScript pour les effets visuels ;
- améliorer les performances globales de vos pages.
Elles redonnent au CSS son rôle premier : celui d’un langage de présentation complet, logique et autonome.
Optimisation et compatibilité
Avant d’adopter massivement les nouveautés comme @property
, la type safety et les animations déclaratives, il est important de comprendre leur compatibilité actuelle, leurs implications sur les performances, et la manière de les intégrer progressivement dans vos projets existants. Comme pour toute nouvelle fonctionnalité du CSS, la clé réside dans une adoption progressive, intelligente et sécurisée.
Navigateurs compatibles et état du support
Le support de @property
et des propriétés typées est encore relativement récent, mais il s’étend rapidement. Ces fonctionnalités sont désormais prises en charge par la majorité des navigateurs modernes.
À ce jour :
- Chrome et Edge (basés sur Chromium) prennent en charge
@property
depuis la version 85. - Safari le supporte également depuis la version 15.4.
- Firefox, quant à lui, travaille activement sur la prise en charge complète, même si certaines fonctionnalités sont encore expérimentales et peuvent nécessiter l’activation d’un flag spécifique dans
about:config
.
Cela signifie que depuis 2025, la très grande majorité des utilisateurs peut profiter de ces nouveautés sans aucun souci.
Cependant, pour garantir un affichage correct sur les navigateurs plus anciens ou non compatibles, il est essentiel d’utiliser des fallbacks (valeurs de secours).
Prenons un exemple simple :
@property --rotation {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.element {
/* Fallback pour les anciens navigateurs */
transform: rotate(0deg);
/* Version moderne */
transform: rotate(var(--rotation));
}
Dans un navigateur qui ne reconnaît pas @property
, la variable --rotation
sera ignorée, mais le style par défaut (ici rotate(0deg)
) sera toujours appliqué.
De cette manière, votre site reste fonctionnel, même sans bénéficier de l’animation déclarative.
Comment vérifier la prise en charge via CSS.supports()
Pour aller plus loin dans la compatibilité, vous pouvez vérifier dynamiquement si le navigateur prend en charge la règle @property
avant d’appliquer certains styles.
JavaScript met à votre disposition la méthode CSS.supports()
, qui permet de tester la présence d’une propriété CSS ou d’une fonctionnalité.
Exemple :
if (CSS.supports('property(--ma-variable)')) {
document.body.classList.add('supporte-property');
} else {
document.body.classList.add('fallback');
}
Dans cet exemple, on ajoute une classe au body
selon que @property
est supporté ou non.
Cela permet d’adapter la feuille de style en conséquence :
body.fallback .element {
background: #3498db;
}
body.supporte-property .element {
background: var(--couleur-dynamique);
transition: --couleur-dynamique 1s ease;
}
Cette méthode est propre, robuste et permet de garder un code maintenable, même dans une phase de transition entre anciens et nouveaux navigateurs.
Fallbacks et dégradés progressifs
L’un des grands principes du CSS moderne repose sur le progressive enhancement, c’est-à-dire l’amélioration progressive.
Autrement dit, le site doit rester utilisable et esthétique, même sans les dernières fonctionnalités, tout en offrant une expérience plus riche aux navigateurs à jour.
Prenons un exemple d’animation de gradient, avec un dégradé animé grâce à @property
, mais avec un fond fixe pour les navigateurs anciens :
body {
background: linear-gradient(45deg, #ff7e5f, #feb47b);
}
/* Pour les navigateurs modernes */
@property --angle {
syntax: '<angle>';
inherits: false;
initial-value: 45deg;
}
@supports (property(--angle)) {
body {
background: linear-gradient(var(--angle), #ff7e5f, #feb47b);
animation: rotation 5s linear infinite;
}
@keyframes rotation {
from { --angle: 45deg; }
to { --angle: 405deg; }
}
}
Ici, même si @property
ou @supports
ne sont pas disponibles, le fond du site reste statique et lisible. Les navigateurs modernes, eux, bénéficieront d’un fond animé, fluide et élégant.
Cette approche est considérée comme la meilleure pratique pour utiliser des fonctionnalités CSS récentes sans casser la compatibilité.
Impact sur les performances
Une idée reçue voudrait que l’ajout de nouvelles déclarations comme @property
alourdisse le rendu. En réalité, c’est souvent l’inverse qui se produit.
Les animations déclaratives sont directement prises en charge par le moteur de rendu du navigateur, sans passer par le moteur JavaScript. Cela signifie qu’elles sont gérées dans un thread séparé (le thread de composition), ce qui les rend beaucoup plus fluides et moins coûteuses en ressources.
Les navigateurs modernes optimisent même les transitions CSS pour qu’elles soient exécutées sur le GPU lorsque c’est possible. Par exemple, les animations de transformation (transform
), d’opacité (opacity
), ou désormais de propriétés personnalisées (@property
) peuvent être accélérées matériellement.
Cependant, certaines précautions restent nécessaires :
- Ne déclarez pas inutilement trop de propriétés
@property
. Chacune d’elles occupe une petite quantité de mémoire, et leur multiplication excessive peut ralentir le chargement initial. - Évitez les animations infinies complexes qui sollicitent fortement le processeur graphique, surtout sur mobile.
- Privilégiez les transitions simples et les effets discrets, plus agréables à l’œil et plus économes en ressources.
Pour mesurer l’impact de vos animations, vous pouvez utiliser les outils intégrés de votre navigateur :
- Dans Chrome ou Edge : ouvrez les DevTools (F12), puis l’onglet Performance. Lancez un enregistrement pour visualiser la charge CPU et la fréquence des frames.
- Dans Firefox : rendez-vous dans Performance > Animations, qui affiche les propriétés animées et leur fréquence d’exécution.
Vous verrez rapidement que les animations déclaratives consomment moins de ressources que leurs équivalents en JavaScript, tout en restant aussi (voire plus) fluides.
Bonnes pratiques d’intégration dans vos projets
Adopter ces nouveautés dans vos projets demande un peu d’organisation, mais quelques règles simples permettent une transition réussie :
- Définissez vos
@property
au début de votre feuille de style, juste après les variables globales du:root
. Cela rend leur présence explicite et facilite la maintenance. - Nommez vos variables avec cohérence, par exemple
--couleur-principale
,--angle-gradient
,--luminosite-theme
. - Testez vos animations sans JavaScript dès le départ, pour profiter pleinement du modèle déclaratif.
- Pensez à l’accessibilité : évitez les animations trop rapides ou permanentes qui peuvent gêner certains utilisateurs (préférez une condition
@media (prefers-reduced-motion: reduce)
pour les désactiver si besoin). - Surveillez la compatibilité : vérifiez régulièrement les évolutions sur caniuse.com pour connaître les dernières versions supportées.
Ces bonnes pratiques vous aideront à tirer le meilleur parti de @property
et des animations déclaratives, sans risquer de compromettre l’expérience utilisateur sur certains appareils.
L’adoption progressive dans le monde professionnel
De plus en plus d’entreprises et de frameworks modernes commencent à intégrer @property
dans leurs bases de code.
Par exemple :
- Google l’utilise déjà dans certaines démos de Material Design pour créer des transitions dynamiques.
- Webflow et d’autres outils de conception visuelle l’intègrent pour permettre aux designers d’ajouter des animations sans coder en JavaScript.
- Des frameworks CSS comme Open Props ou Modern Normalize commencent à exploiter le typage et les variables animables pour standardiser les comportements.
Cela confirme que ces fonctionnalités ne sont pas de simples expérimentations, mais bien un tournant durable dans l’évolution du langage CSS.
Étude de cas complète : créer un bouton dynamique 100 % CSS
Pour conclure cette série de chapitres techniques, rien de tel qu’un cas concret. Nous allons réaliser ensemble un bouton animé, élégant et interactif, entièrement en CSS — sans la moindre ligne de JavaScript.
L’objectif est de mettre en pratique tout ce que nous avons appris : la déclaration d’une propriété typée avec @property
, l’utilisation de la type safety, et la création d’animations déclaratives fluides et performantes.
L’exercice vous permettra de comprendre comment ces outils s’intègrent dans un projet réel, tout en respectant les principes d’accessibilité et d’optimisation que nous avons vus précédemment.
Objectif : un bouton qui réagit avec fluidité
L’idée est de créer un bouton qui :
- change de couleur lorsqu’on le survole ;
- se contracte légèrement au clic (effet de pression) ;
- affiche une subtile lueur animée autour de lui, donnant une impression de profondeur.
Le tout doit rester lisible, fluide et compatible avec les navigateurs récents.
Préparation de la base HTML et CSS
Commençons par la structure HTML la plus simple possible.
Nous avons seulement besoin d’un bouton :
<button class="btn-dynamique">Cliquez ici</button>
Ensuite, créons la base CSS du bouton avant d’y ajouter les effets dynamiques.
.btn-dynamique {
font-size: 1.2rem;
font-weight: bold;
color: white;
background-color: var(--couleur-fond, #3498db);
border: none;
border-radius: 12px;
padding: 1rem 2rem;
cursor: pointer;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
À ce stade, le bouton est déjà esthétique et réactif grâce à la transition sur transform
et box-shadow
.
Mais nous allons aller beaucoup plus loin.
Déclaration des propriétés personnalisées typées
Nous allons maintenant déclarer plusieurs propriétés CSS personnalisées avec @property
pour rendre notre bouton plus interactif et expressif.
@property --couleur-fond {
syntax: '<color>';
inherits: false;
initial-value: #3498db;
}
@property --intensite-lueur {
syntax: '<number>';
inherits: false;
initial-value: 0;
}
@property --echelle {
syntax: '<number>';
inherits: false;
initial-value: 1;
}
Explication :
--couleur-fond
représente la couleur de fond du bouton. Grâce à son typage<color>
, elle peut être animée.--intensite-lueur
contrôle la luminosité de la lueur autour du bouton.--echelle
permet de faire varier la taille du bouton lors de l’interaction.
Ces variables étant typées, le navigateur sait désormais comment interpoler leurs valeurs pour créer des transitions fluides.
Application des variables et transitions
Nous allons utiliser ces variables dans le style du bouton et définir les transitions sur ces propriétés personnalisées :
.btn-dynamique {
background-color: var(--couleur-fond);
transform: scale(var(--echelle));
box-shadow: 0 0 calc(var(--intensite-lueur) * 10px) var(--couleur-fond);
transition:
--couleur-fond 0.5s ease,
--intensite-lueur 0.5s ease,
--echelle 0.2s ease;
}
Le bouton tire désormais sa couleur, sa taille et sa lueur des variables déclarées précédemment.
Chaque variable est animable grâce à @property
, et la transition s’appliquera automatiquement dès qu’une valeur changera.
Création des interactions : survol et clic
Nous allons maintenant ajouter des interactions naturelles pour le survol (:hover
) et le clic (:active
).
.btn-dynamique:hover {
--couleur-fond: #2ecc71;
--intensite-lueur: 1;
}
.btn-dynamique:active {
--echelle: 0.95;
--intensite-lueur: 1.5;
}
Voici ce qu’il se passe :
- Lorsque l’utilisateur survole le bouton, la couleur passe du bleu au vert, et une lueur douce apparaît.
- Lorsqu’il clique dessus, le bouton se contracte légèrement, simulant un effet de pression, et la lueur devient plus intense.
Toutes ces transitions sont gérées par le navigateur, sans script ni re-rendu forcé. Le résultat est fluide et réactif.
Animation continue de la lueur
Nous pouvons aller encore plus loin en ajoutant une animation déclarative continue sur la lueur, pour donner un effet de pulsation discrète.
@keyframes pulsation {
0% { --intensite-lueur: 0.5; }
50% { --intensite-lueur: 1.2; }
100% { --intensite-lueur: 0.5; }
}
.btn-dynamique {
animation: pulsation 4s ease-in-out infinite;
}
Désormais, même au repos, le bouton conserve une lueur subtile et vivante.
Grâce à @property
, cette animation est interprétée de manière déclarative, avec un excellent rendu visuel.
Gestion du mode réduit (accessibilité)
Par respect pour les utilisateurs sensibles aux animations, il est important de respecter la préférence système prefers-reduced-motion
.
Nous pouvons facilement désactiver l’effet de pulsation pour ces utilisateurs :
@media (prefers-reduced-motion: reduce) {
.btn-dynamique {
animation: none;
--intensite-lueur: 0;
}
}
Ainsi, le bouton reste fonctionnel et esthétique, mais sans mouvement inutile.
Cette approche illustre parfaitement comment le CSS moderne peut être à la fois esthétique, performant et inclusif.
Résultat final et explication détaillée
Voici le code complet réuni :
@property --couleur-fond {
syntax: '<color>';
inherits: false;
initial-value: #3498db;
}
@property --intensite-lueur {
syntax: '<number>';
inherits: false;
initial-value: 0;
}
@property --echelle {
syntax: '<number>';
inherits: false;
initial-value: 1;
}
@keyframes pulsation {
0% { --intensite-lueur: 0.5; }
50% { --intensite-lueur: 1.2; }
100% { --intensite-lueur: 0.5; }
}
.btn-dynamique {
font-size: 1.2rem;
font-weight: bold;
color: white;
background-color: var(--couleur-fond);
border: none;
border-radius: 12px;
padding: 1rem 2rem;
cursor: pointer;
transform: scale(var(--echelle));
box-shadow: 0 0 calc(var(--intensite-lueur) * 10px) var(--couleur-fond);
transition:
--couleur-fond 0.5s ease,
--intensite-lueur 0.5s ease,
--echelle 0.2s ease;
animation: pulsation 4s ease-in-out infinite;
}
.btn-dynamique:hover {
--couleur-fond: #2ecc71;
--intensite-lueur: 1;
}
.btn-dynamique:active {
--echelle: 0.95;
--intensite-lueur: 1.5;
}
@media (prefers-reduced-motion: reduce) {
.btn-dynamique {
animation: none;
--intensite-lueur: 0;
}
}
Ce que nous obtenons :
- Un bouton dynamique, fluide et performant.
- Des transitions harmonieuses entre les états.
- Une animation continue purement déclarative.
- Une compatibilité avec les préférences d’accessibilité.
- Zéro JavaScript.
Ce type de composant peut facilement être intégré à un site vitrine, une application web ou un tableau de bord. Il démontre la puissance des nouvelles fonctionnalités CSS modernes, et surtout leur capacité à simplifier le travail du développeur tout en améliorant la qualité de l’expérience utilisateur.
le CSS moderne, plus intelligent que jamais
Nous venons de traverser ensemble un chapitre passionnant de l’évolution du langage CSS.
Avec @property
, la type safety et les animations déclaratives, le CSS franchit une nouvelle étape : il devient un langage vivant, fiable et expressif, capable de gérer des comportements autrefois réservés au JavaScript.
Moins de JavaScript, plus de sens !
L’époque où tout passait par des scripts complexes est révolue.
Aujourd’hui, le navigateur sait :
- interpoler des couleurs, des nombres ou des longueurs grâce à des propriétés typées ;
- gérer les transitions de manière native, sans déclencher de recalculs forcés ;
- synchroniser animations et performances graphiques via le moteur CSS.
Cela allège le code, réduit les dépendances, et améliore la lisibilité comme la maintenabilité.
En d’autres termes : le style devient logique.
Une approche déclarative et prédictive
L’avantage majeur de cette nouvelle approche est qu’elle favorise la prévisibilité du rendu.
En déclarant clairement le type et la valeur initiale d’une propriété, le navigateur peut anticiper les interpolations et offrir une expérience fluide, sans à-coups.
Là où autrefois un simple “clignotement” nécessitait du JavaScript, il suffit désormais d’un @keyframes
et d’un @property
.
C’est un gain considérable en :
- performance (le moteur CSS est hautement optimisé) ;
- clarté (les comportements sont visibles directement dans la feuille de style) ;
- collaboration (les designers et développeurs front peuvent enfin parler le même langage).
Une frontière qui s’efface entre design et interaction
Les nouvelles fonctionnalités CSS abolissent progressivement la séparation rigide entre “apparence” et “comportement”.
Les interactions visuelles peuvent être décrites, comprises et animées sans quitter le langage du style.
Cela ouvre la voie à des composants :
- plus cohérents visuellement,
- plus accessibles,
- et plus faciles à maintenir sur le long terme.
Les designers peuvent penser dynamique, les développeurs peuvent penser déclaratif — et les deux peuvent enfin travailler sur une base commune.
Ce qu’il faut retenir
@property
permet de déclarer des variables CSS typées et animables.- La type safety réduit les erreurs et améliore la cohérence du rendu.
- Les animations déclaratives remplacent avantageusement une grande partie du JavaScript d’interaction.
- Ces outils sont déjà supportés par la majorité des navigateurs modernes.
- Et surtout : ils rendent le code plus élégant, plus fluide et plus durable.
Nous ne sommes qu’au début d’une nouvelle ère du CSS.
Les prochaines évolutions — comme les CSS Houdini APIs, les custom paint worklets, ou encore les cascade layersavancées — vont encore renforcer cette approche modulaire, performante et sémantique.
le CSS n’est plus un simple langage de style. C’est un véritable moteur de création interactive.