Animer la teinte OKLCH avec @property (Houdini) — onde, stagger, combinaisons
Cela t'intéresse ? Cet article s'adresse à quelqu'un qui connaît
déjà les variables CSS (--ma-variable) et les animations
(@keyframes). La matrice de lettres polygonales n'est pas
un prérequis, mais elle sert de terrain de jeu.
Prérequis : bases de CSS, notions d'OKLCH (voir l'accueil du lab), lecture de Matrice SQI recommandée.
L'expérience : Est-il facile et amusant 'animer une propriété CSS custom de manière fluide et synchronisée ? Peut-on faire du CSS pur pour créer un effet d'onde encapsulé sur un mot, et de combiner plusieurs animations indépendantes sur un même élément.
On veut animer la couleur d'un mot lettre par lettre, il existe plusieurs façons de créer des effets qui ressemblent à une onde chromatique qui traverse le texte de gauche à droite. Chaque lettre doit avoir sa propre teinte à chaque instant.
Première tentative : animer background-color directement.
Ça fonctionne… mais l'ombre drop-shadow reste figée. C'est moche.
Les deux propriétés ne sont pas synchronisées et elles ne partagent pas la
même source de vérité (la teinte).
Deuxième tentative : stocker la teinte dans une variable CSS
--dynamic-h et l'animer dans un @keyframes.
Résultat : rien ne bouge. Le navigateur voit la variable
comme une chaîne de texte opaque. Il ne sait pas qu'il s'agit d'un nombre.
Il passe brutalement de la valeur de départ à la valeur d'arrivée, sans
interpoler. Mission accomplie ? Pas vraiment.
Sans un mécanisme pour typer la variable, l'animation de teinte coordonnée entre plusieurs propriétés est impossible en CSS pur.
L'API @property (Houdini CSS) permet d'enregistrer
une propriété CSS custom avec un type. Une fois typée, le
navigateur peut interpoler entre deux valeurs exactement comme il le ferait
avec width ou opacity.
La syntaxe déclare trois choses :
syntax : le type de la valeur ('<number>',
'<length>', '<color>'…) on l'explique dans la page Syntaxe des propriétés CSS custom.inherits : si la valeur se propage aux enfantsinitial-value : la valeur par défaut avant tout calculCouplé à oklch(L C H), on peut animer H (la
teinte) sur un tour complet du cercle chromatique (0 → 360). En OKLCH,
contrairement à HSL, la luminosité perçue reste constante
pendant ce tour. L'onde est propre, sans saut visuel.
Le stagger (décalage temporel) consiste à donner à chaque
lettre un animation-delay différent. Chaque élément joue la
même animation, mais à un instant décalé. Le résultat est une propagation
spatiale de la couleur — une onde.
Une règle at-rule CSS qui enregistre une propriété custom avec un type natif, permettant son interpolation par le moteur d'animation.
Dès qu'on veut animer une variable CSS de manière fluide —
particulièrement utile quand plusieurs propriétés (filter,
background, border-color…) doivent
réagir à la même valeur en temps réel.
Animer background-color directement ne synchronise
pas l'ombre. Animer une variable CSS sans @property
ne produit aucune interpolation. @property est le
seul mécanisme CSS natif qui résout les deux problèmes à la fois.
Le mot COMBAT en onde chromatique saccadée (steps(15)) :
Chaque polygone a sa propre teinte à chaque instant T. L'ombre
drop-shadow suit exactement la même équation OKLCH —
aucune désynchronisation possible car les deux lisent
--dynamic-h.
Sans syntax: '<number>', l'interpolation est
impossible. C'est le prérequis absolu. Une variable non typée
ne peut pas être animée de manière fluide.
Toutes les propriétés visuelles liées à la même valeur (couleur, ombre, bordure…) doivent lire la même variable. Ne jamais dupliquer la valeur dans plusieurs propriétés indépendantes.
En HSL, un tour de cercle chromatique produit des sauts de luminosité perçue. En OKLCH, la luminosité reste perceptuellement constante. Pour une onde propre, OKLCH est obligatoire.
Toute animation doit être désactivée si l'utilisateur a activé
la préférence système de mouvement réduit. La règle
@media (prefers-reduced-motion: reduce) est
non négociable.
@property transforme une variable CSS en donnée typée,
animable nativement par le moteur du navigateur. Combiné à OKLCH,
il permet des effets chromatiques fluides et perceptuellement cohérents,
sans JavaScript.
Les trois règles essentielles : typer la variable, une seule source de vérité, OKLCH pour les teintes.
Quelques pistes à explorer depuis ici :
steps),
fluide (linear), ou combinée avec une animation
d'épaisseur matrice en parallèle. Voir les démos ci-dessous.@property --offset pour animer l'épaisseur du trait.