Le CSS continue d’évoluer avec des fonctionnalités de plus en plus puissantes. Parmi elles, @property en CSS permet de déclarer des propriétés personnalisées exploitables dans les animations et transitions. Associé à position-anchor et :has(), cet outil offre des effets dynamiques sans JavaScript.
Dans cet article, nous allons analyser un exemple concret qui exploite @property en CSS pour créer une interaction fluide avec des boutons radio.
Boutons radio rebondissants utilisant un CSS moderne

@property --_x {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
.container {
--s: 1em; /* control the size */
--c: #009688; /* the active color */
display: grid;
position: relative;
}
.container:before {
content: "";
position: absolute;
position-anchor: --checkbox;
height: calc(var(--s)/2);
aspect-ratio: 1;
--_y: clamp(-1,var(--_x)*9999,1); /* until better support for sign() */
left: max(-80px,var(--s)/4 - var(--_x)*var(--_y)*1px);
top: calc(anchor(top) + var(--s)/4);
background: var(--c);
border-radius: 50%;
transition: top .4s linear,--_x cubic-bezier(.1,3000,.7,3000) .4s;
}
input {
height: var(--s);
aspect-ratio: 1;
border: calc(var(--s)/8) solid #939393;
border-radius: 50%;
outline-offset: calc(var(--s)/10);
appearance: none;
transition: .3s .1s;
}
input:checked {
border-color: var(--c);
anchor-name: --checkbox;
}
/* The hacky part ... */
.container:has(label:nth-child(1) input:checked):before {--_x:.01}
.container:has(label:nth-child(2) input:checked):before {--_x:.02}
.container:has(label:nth-child(3) input:checked):before {--_x:.03}
/* .container:has(label:nth-child(N) input:checked):before {--_x:.0N}*/🧐 Qu’est-ce que @property en CSS ?
1️⃣ Définition et utilité
@property --_x {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
La directive @property permet d’introduire des propriétés CSS personnalisées compatibles avec les animations et transitions. Contrairement aux variables CSS classiques (--my-var), ces propriétés peuvent être animées.
📌 Pourquoi utiliser @property en CSS ?
✅ Contrôle avancé sur les animations
✅ Optimisation des performances
✅ Évite d’avoir recours à JavaScript
👉 Ici, --_x servira à contrôler la position dynamique de notre élément animé.
2️⃣ Création du conteneur interactif
.container {
--s: 1em; /* Contrôle la taille */
--c: #009688; /* Couleur active */
display: grid;
position: relative;
}
Le conteneur utilise des variables CSS dynamiques pour la taille (--s) et la couleur (--c). Il fonctionne comme un espace interactif où notre animation va se produire.
3️⃣ Animer un élément avec @property en CSS
.container:before {
content: "";
position: absolute;
position-anchor: --checkbox;
height: calc(var(--s)/2);
aspect-ratio: 1;
--_y: clamp(-1,var(--_x)*9999,1);
left: max(-80px,var(--s)/4 - var(--_x)*var(--_y)*1px);
top: calc(anchor(top) + var(--s)/4);
background: var(--c);
border-radius: 50%;
transition: top .4s linear, --_x cubic-bezier(.1,3000,.7,3000) .4s;
}
🟢 Ce qu’il se passe ici :
🔹 position-anchor: --checkbox : Ancre l’élément en fonction du bouton sélectionné.
🔹 --_x et clamp() : Ajuste dynamiquement la position de l’élément.
🔹 transition avec cubic-bezier() : Applique un effet d’animation progressif et naturel.
4️⃣ Interaction avec des inputs radio
input {
height: var(--s);
aspect-ratio: 1;
border: calc(var(--s)/8) solid #939393;
border-radius: 50%;
outline-offset: calc(var(--s)/10);
appearance: none;
transition: .3s .1s;
}
input:checked {
border-color: var(--c);
anchor-name: --checkbox;
}
✅ Explications :
- Les boutons radio sont personnalisés avec un
aspect-ratio: 1pour les rendre circulaires. - Lorsqu’un
inputest coché, il change de couleur et devient une ancre (anchor-name: --checkbox). - Supprime l’apparence par défaut avec
appearance: none
5️⃣ La magie du :has() pour déclencher l’animation
.container:has(label:nth-child(1) input:checked):before {--_x:.01}
.container:has(label:nth-child(2) input:checked):before {--_x:.02}
.container:has(label:nth-child(3) input:checked):before {--_x:.03}
🔥 Utilisation astucieuse de :has()
- Détecte un
input:checkedsans JavaScript - Modifie dynamiquement
--_xpour animer l’élément - Compatible avec tous les labels (
nth-child(N)) pour gérer plusieurs options
🎬 Conclusion
L’utilisation de @property en CSS combinée à :has() et position-anchor ouvre de nouvelles possibilités en matière d’animation et d’interaction web, sans nécessiter JavaScript.
Avantages de cette approche :
✅ Aucune dépendance JavaScript
✅ Animation CSS performante
✅ Compatible avec des styles adaptatifs
💡 Possibilités d’amélioration ?
- Tester la compatibilité sur divers navigateurs (🚨
position-anchorn’est pas encore largement supporté). - Ajouter des effets supplémentaires comme une échelle (
transform: scale()). - Intégrer ce principe dans des UI interactives avancées.
🚀 Que pensez-vous de cette technique ? Avez-vous déjà expérimenté @property dans vos projets ?





