@property en CSS : créez des animations dynamiques sans JavaScript

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

CSS développement
CSS développement
@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: 1 pour les rendre circulaires.
  • Lorsqu’un input est 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:checked sans JavaScript
  • Modifie dynamiquement --_x pour 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-anchor n’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 ?

0 0 votes
Évaluation de l'article
0 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
0
Nous aimerions avoir votre avis, veuillez laisser un commentaire.x