Communitygithub.com

Mad7droid/ux-motion

Concevez, implémentez et auditez les animations UI pour les transitions, gestes, retours et surfaces interactives. À utiliser pour ajouter du mouvement ou corriger des interactions lentes, saccadées ou distrayantes. Ignore le travail non visuel et les animations de graphiques.

Qu'est-ce que ux-motion ?

Cette compétence (skill) fournit un guide complet pour concevoir et implémenter des animations UI (mouvement) de haute qualité dans des applications web. Elle est destinée aux développeurs et aux agents IA travaillant sur des projets où l'expérience utilisateur visuelle est primordiale. La compétence définit des règles strictes concernant les durées d'animation (généralement 120-180 ms), les courbes d'accélération (avec des easings d'entrée et de sortie), et l'utilisation de propriétés CSS performantes comme `transform` et `opacity` pour éviter les mises en page coûteuses. Elle met l'accent sur l'accessibilité en exigeant le respect de la préférence `prefers-reduced-motion`, le remplacement du mouvement par des changements d'opacité ou de couleur, et la préservation de la compréhension de l'interface. La compétence couvre en détail la gestion des gestes (avec `setPointerCapture()` pour le drag), le traitement des interruptions (retargeting des animations), et l'utilisation de ressorts (springs) pour des interactions plus naturelles. Elle fournit également une méthode de vérification rigoureuse, incluant le ralenti, les tests de réduction de mouvement et les tests sur des appareils physiques, ainsi qu'un format de rapport d'audit pour les revues de code. Elle est conçue pour être utilisée avec des agents comme Claude Code, Cursor ou Codex, et les valeurs par défaut peuvent être surchargées par des jetons de projet (design tokens).

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Mad7droid/mad-ux-motion/tree/main/skills/ux-motion

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Mouvement UX (UX motion)

Appliquez ces règles lors de la conception et de l'écriture de l'interaction. Inspectez d'abord les jetons de mouvement du projet : les fichiers AGENTS.md, CLAUDE.md, les fichiers de jetons et les docs de conception remplacent les valeurs par défaut ci-dessous.

Cœur toujours actif

  • Décision par défaut : l'interface utilisateur fonctionnelle se situe généralement dans une bande de 120 à 180 ms. Les jetons du projet l'emportent.
  • Animez pour la continuité spatiale, le changement d'état, le retour d'information sur une saisie, ou pour éviter une apparition brutale.
  • Préférez les transitions nommées transform et opacity. N'utilisez jamais transition: all.
  • Les surfaces qui apparaissent doivent décélérer ; les surfaces qui disparaissent doivent accélérer. Les sorties peuvent être plus courtes.
  • Commencez les surfaces mises à l'échelle près de scale(0.96), jamais à partir de scale(0).
  • Maintenez le mouvement remplaçable sous prefers-reduced-motion: reduce ; préservez la compréhension et l'accès au clavier.
  • Capturez le pointeur pour les glissés, protégez les touches secondaires et testez les gestes sur du matériel.
  • Avant d'écrire du mouvement ou de toucher à une superposition courante, lisez ce fichier en entier. Utilisez REFERENCE.md uniquement pour les chemins de détourage, la 3D, l'API WAAPI ou les analyses de performance approfondies.

1. Décidez si le mouvement est justifié

Utilisez la fréquence d'exposition comme contrainte : les actions répétées constamment doivent être instantanées ou presque ; les surfaces occasionnelles peuvent établir une continuité spatiale ; les moments rares et explicatifs peuvent avoir plus de personnalité. Le mouvement doit clarifier un changement, accuser réception d'une entrée, préserver un emplacement ou éviter une apparition brutale. S'il ne fait rien de tout cela, supprimez-le. Ne faites pas attendre un raccourci clavier pour un mouvement décoratif.

2. Choisissez une durée

La bande 120–180 ms est une décision par défaut : elle est intentionnellement plus serrée que la plage courte3 (150 ms), courte4 (200 ms) et la plage de transition standard (250–400 ms) publiées par Material 3. Elle exprime une préférence contre une interface utilisateur fonctionnelle lente, et non une exigence d'accessibilité ou de plateforme publiée.

SurfacePoint de départ
Retour de pression (feedback press)100–140 ms
Infobulle (tooltip) ou petit popover120–160 ms
Menu ou liste déroulante (dropdown)140–180 ms
Fenêtre modale (modal)180 ms
Feuille (sheet)180 ms ; jusqu'à 250 ms lorsqu'elle parcourt la majeure partie de la fenêtre d'affichage

Utilisez la valeur la plus courte pour les sorties. Ce sont des valeurs par défaut, pas des surcharges pour les jetons du produit.

3. Choisissez un assouplissement (easing)

Une surface qui entre doit arriver avec une emphase qui s'installe (décélère) ; une sortie doit s'effacer rapidement (accélère). Material 3 nomme ces directions explicitement :

:root {
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --ease-enter: cubic-bezier(0.05, 0.7, 0.1, 1); /* emphasized-decelerate */
  --ease-exit: cubic-bezier(0.3, 0, 0.8, 0.15); /* emphasized-accelerate */
}

Utilisez linear uniquement pour une progression de type temporelle. Utilisez une courbe ease-in-out pour un état qui traverse un point médian délibéré. Évitez de choisir une courbe uniquement par son nom : inspectez la forme tracée et la direction du déplacement.

4. Gardez le rendu léger

Préférez transform et opacity, qui peuvent rester sur le compositeur. Nommez les propriétés et évitez d'impliquer la mise en page dans l'animation. Évitez d'animer top, left, width, height, la marge (margin) ou le remplissage (padding) à moins que le changement de mise en page ne soit le but et que le coût soit accepté. Pour la hauteur intrinsèque, un wrapper peut faire la transition grid-template-rows: 0fr vers 1fr, avec un wrapper intérieur min-height: 0 masqué par overflow: hidden. Cela effectue toujours une mise en page ; profilez-le plutôt que de le traiter comme un raccourci du compositeur uniquement. Utilisez will-change tardivement, brièvement, et seulement après que le profilage montre qu'il aide ; les couches consomment des ressources.

5. Rendez les états corrects

  • Donnez un retour visible aux éléments pressables ; utilisez un état de couleur, de bordure ou d'ombre existant, ou un petit scale(0.98) lorsque cela convient. N'écrasez pas une transformation de positionnement.
  • Préservez le focus visible, l'activation au clavier et le comportement désactivé. L'animation ne doit pas retarder le placement du focus, la gestion de la touche Échap ou les mises à jour d'état sémantique.
  • Les popovers, menus et infobullies grandissent à partir d'un point d'ancrage via transform-origin ; les fenêtres modales centrées grandissent à partir du centre. Gardez l'origine stable pendant que l'état change.
  • Préférez les transitions pour les états qui peuvent être déclenchés à nouveau. Utilisez des keyframes pour un événement autonome.
  • Limitez les effets au survol uniquement avec @media (hover: hover) and (pointer: fine).
  • Pour un élément qui entre, utilisez @starting-style là où c'est pris en charge, ou un état monté qui rend le style initial observable avant la transition.

6. Mouvement réduit signifie un remplacement

Le réglage prefers-reduced-motion couvre le mouvement supprimé, réduit ou remplacé ; le panoramique et le zoom à grande échelle peuvent être des déclencheurs vestibulaires. Remplacez le déplacement et l'échelle par des changements d'opacité et de couleur là où ceux-ci expliquent encore l'état. Gardez les changements de focus, de chargement et de visibilité compréhensibles. Ne faites pas disparaître un élément simplement parce que l'utilisateur a demandé moins de mouvement. Honorez cette préférence dans les animations pilotées par JavaScript ainsi que par CSS, y compris les changements de préférence pendant que la page est ouverte. Ne dépendez pas d'un événement transitionend pour terminer un changement d'état essentiel : la transition peut être désactivée ou annulée. Limitez les surcharges au composant affecté au lieu de forcer globalement chaque animation à une durée minuscule.

7. Gestes

Appelez setPointerCapture() lorsqu'un glissé commence : les événements de pointeur ultérieurs continueront alors à cibler l'élément de capture jusqu'au relâchement. Fermez (dismiss) sur une règle de vélocité ou distance ajustée ; il n'y a pas de constante de flick universelle, donc calibrez-la sur l'appareil réel. Maintenez le mouvement borné avec un amortissement (damping) au lieu d'un bord dur. Ignorez les points de contact supplémentaires une fois qu'un geste possède le pointeur. Laissez l'utilisateur inverser un geste en cours. Gérez pointercancel et lostpointercapture en effaçant l'état de glissé. Choisissez touch-action pour l'axe du geste sans bloquer inutilement le défilement de la page ; fournissez un bouton ou un équivalent clavier.

8. Gérez l'interruption et les ressorts (springs)

Une ouverture/fermeture/réouverture rapide doit aboutir au dernier état demandé. Reciblez à partir de l'état visuel actuel plutôt que de rejouer depuis le début. Annulez les callbacks, écouteurs et animations obsolètes lors du remplacement ou du démontage ; une ancienne sortie ne doit pas supprimer une surface nouvellement rouverte. Gardez le contenu caché ou en cours de sortie hors de la navigation au clavier selon le cycle de vie du focus du composant.

Utilisez un ressort (spring) lorsque la manipulation directe ou la continuité en bénéficie, en respectant la bibliothèque du projet. Les paramètres de ressort varient entre les moteurs : ne copiez pas aveuglément les valeurs de rigidité et d'amortissement. Réglez le temps d'établissement et le dépassement (overshoot) sur le composant réel ; évitez le rebond sur les surfaces riches en texte et désactivez le déplacement en mouvement réduit.

9. Vérifiez avant de déclarer terminé

Rejouez à une vitesse 4× plus lente et vérifiez que les propriétés se terminent ensemble et proviennent du bon endroit. Basculez rapidement pour exposer les accrocs. Émulez le mouvement réduit dans les DevTools. Exercez un glissé au-delà de son bord, annulez-le, ajoutez un deuxième contact et testez sur un appareil physique. Pour les valeurs d'animation calculées à l'exécution, consultez REFERENCE.md. Indiquez quelles vérifications ont été réellement effectuées et lesquelles nécessitent un navigateur ou un appareil physique ; la seule revue de code ne peut pas établir la fluidité perçue.

Examiner la sortie (output)

Lors de l'audit du code, rapportez un tableau concis, le plus grave en premier :

Fichier:ligneMaintenantRemplacer parPourquoi
Menu.tsx:18transition: all 300mspropriétés nommées et jetons du projetévite l'animation de mise en page accidentelle

Ne rapportez que les résultats visibles dans le code. Si la diff est propre, dites-le plutôt que d'inventer des résultats.

Organisé par mad7droid.

Skills associés