Synthèse automatique
Guide pratique pour ajouter des animations et micro-interactions fluides dans une interface React avec Framer Motion et CSS.
Points forts
- Fournit des exemples concrets pour les animations d'entrée/sortie, les gestes, les listes, les transitions de mise en page et les effets au scroll.
- Rappelle les bons principes de performance, notamment l'usage de transform et opacity, ainsi que des durées courtes.
- Inclut le respect de la préférence reduced motion et une recherche de cohérence dans les courbes d'animation.
Limites
- Très centré sur React et Framer Motion, avec peu de contenu CSS malgré la description.
- Le fichier fourni est tronqué et ne détaille pas l'installation, les versions compatibles ni les tests.
- Les exemples supposent une stack TSX avec Tailwind et ne couvrent pas tous les frameworks front-end.
À utiliser lorsqu'on veut ajouter rapidement des animations d'interface soignées et accessibles dans un projet React.
À éviter si le projet n'utilise pas React/Framer Motion ou si l'on cherche une solution d'animation purement CSS sans dépendance.
Analyse de sécurité
SûrThis is a purely instructional front-end design document containing React/Framer Motion and CSS code snippets. It declares no tools and contains no shell commands, network calls, filesystem operations, or obfuscated payloads. The only executable-looking content is ordinary UI code examples, so there is no meaningful execution risk.
Aucun point d'attention détecté
Comment cette analyse est faiteExemples
Add an accessible modal to my React app with Framer Motion: backdrop fade and content scale/fade using AnimatePresence, 200ms duration, and respect prefers-reduced-motion.Create a staggered reveal animation for a list of dashboard cards using Framer Motion variants with 0.1s stagger and a subtle slide-up.Build a tab bar in React where the active indicator slides between tabs using Framer Motion layoutId and a spring transition.name: animation-motion description: Create smooth animations and micro-interactions with Framer Motion and CSS. Covers enter/exit animations, gestures, scroll animations, loading states, and performance optimization. Use for polished UIs, interactive elements, and engaging user experiences.
Animation & Motion Design
Create smooth, purposeful animations that enhance user experience.
Instructions
- Animate with purpose - Every animation should serve a function
- Keep it subtle - 200-400ms for most UI transitions
- Respect reduced motion - Honor user preferences
- Optimize performance - Use transform and opacity
- Use consistent easing - Create a motion language
Framer Motion Basics
Simple Animations
import { motion } from 'framer-motion';
// Fade in on mount
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3 }}
>
Content
</motion.div>
// Slide up with spring
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{
type: 'spring',
stiffness: 300,
damping: 30,
}}
>
Content
</motion.div>
Exit Animations
import { AnimatePresence, motion } from 'framer-motion';
function Modal({ isOpen, onClose, children }) {
return (
<AnimatePresence>
{isOpen && (
<>
{/* Backdrop */}
<motion.div
className="fixed inset-0 bg-black/50"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={onClose}
/>
{/* Modal content */}
<motion.div
className="fixed inset-0 flex items-center justify-center"
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.95 }}
transition={{ duration: 0.2 }}
>
{children}
</motion.div>
</>
)}
</AnimatePresence>
);
}
Gesture Animations
import { motion } from 'framer-motion';
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
transition={{ type: 'spring', stiffness: 400, damping: 17 }}
>
Click me
</motion.button>
// Drag
<motion.div
drag
dragConstraints={{ left: 0, right: 300, top: 0, bottom: 300 }}
dragElastic={0.1}
whileDrag={{ scale: 1.1 }}
>
Drag me
</motion.div>
List Animations
import { motion } from 'framer-motion';
const container = {
hidden: { opacity: 0 },
show: {
opacity: 1,
transition: {
staggerChildren: 0.1,
},
},
};
const item = {
hidden: { opacity: 0, y: 20 },
show: { opacity: 1, y: 0 },
};
function List({ items }) {
return (
<motion.ul
variants={container}
initial="hidden"
animate="show"
>
{items.map((data) => (
<motion.li key={data.id} variants={item}>
{data.title}
</motion.li>
))}
</motion.ul>
);
}
Layout Animations
import { motion, LayoutGroup } from 'framer-motion';
function Tabs({ tabs, activeTab, onTabChange }) {
return (
<LayoutGroup>
<div className="flex space-x-2">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => onTabChange(tab.id)}
className="relative px-4 py-2"
>
{tab.label}
{activeTab === tab.id && (
<motion.div
layoutId="activeTab"
className="absolute inset-0 bg-blue-100 rounded-lg"
style={{ zIndex: -1 }}
transition={{ type: 'spring', stiffness: 500, damping: 30 }}
/>
)}
</button>
))}
</div>
</LayoutGroup>
);
}
Scroll Animations
import { motion, useScroll, useTransform } from 'framer-motion';
function ParallaxHero() {
const { scrollY } = useScroll();
const y = useTransform(scrollY, [0, 500], [0, 150]);
const opacity = useTransform(scrollY, [0, 300], [1, 0]);
return (
<motion.div
style={{ y, opacity }}
className="h-screen flex items-center justify-center"
>
<h1 className="text-6xl font-bold">Welcome</h1>
</motion.div>
);
}
// Scroll-triggered animation
import { useInView } from 'framer-motion';
function FadeInSection({ children }) {
const ref = useRef(null);
const isInView = useInView(ref, { once: true, margin: '-100px' });
return (
<motion.div
ref={ref}
initial={{ opacity: 0, y: 50 }}
animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 50 }}
transition={{ duration: 0.5 }}
>
{children}
</motion.div>
);
}
CSS Animations
Keyframe Animations
/* Tailwind config */
animation: {
'fade-in': 'fadeIn 0.3s ease-out',
'slide-up': 'slideUp 0.3s ease-out',
'spin-slow': 'spin 3s linear infinite',
'pulse-subtle': 'pulse 2s ease-in-out infinite',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
slideUp: {
'0%': { transform: 'translateY(10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
}
Transition Classes
// Hover transitions
<button className="
transition-all duration-200 ease-out
hover:scale-105 hover:shadow-lg
active:scale-95
">
Click me
</button>
// Color transitions
<div className="
transition-colors duration-300
bg-gray-100 hover:bg-gray-200
dark:bg-gray-800 dark:hover:bg-gray-700
">
Content
</div>
Loading States
Skeleton Loading
function SkeletonCard() {
return (
<div className="animate-pulse">
<div className="h-48 bg-gray-200 rounded-lg" />
<div className="mt-4 space-y-3">
<div className="h-4 bg-gray-200 rounded w-3/4" />
<div className="h-4 bg-gray-200 rounded w-1/2" />
</div>
</div>
);
}
Spinner Component
function Spinner({ size = 'md' }) {
const sizes = {
sm: 'w-4 h-4',
md: 'w-6 h-6',
lg: 'w-8 h-8',
};
return (
<svg
className={`animate-spin ${sizes[size]} text-blue-600`}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
/>
</svg>
);
}
Reduced Motion Support
import { useReducedMotion } from 'framer-motion';
function AnimatedComponent() {
const shouldReduceMotion = useReducedMotion();
return (
<motion.div
initial={{ opacity: 0, y: shouldReduceMotion ? 0 : 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: shouldReduceMotion ? 0 : 0.3 }}
>
Content
</motion.div>
);
}
// CSS approach
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Performance Tips
- Animate transform and opacity only - GPU accelerated
- Use
will-changesparingly - For complex animations - Avoid layout thrashing - Don't animate width/height
- Use
AnimatePresencemode="wait" - Prevent animation overlap - Lazy load animations - For below-fold content
// GPU-optimized animation
<motion.div
animate={{ x: 100 }} // Good: transform
// animate={{ left: 100 }} // Bad: layout property
/>
// will-change for complex animations
<div style={{ willChange: 'transform' }}>
Heavy animation here
</div>
Best Practices
- 200-400ms for transitions - Feels responsive
- Spring for interactive elements - Natural feel
- Ease-out for enter - Elements arrive and settle
- Ease-in for exit - Elements accelerate away
- Stagger lists - 50-100ms between items
- Match motion to meaning - Slide for navigation, fade for content
When to Use
- Page transitions and navigation
- Modal and dialog animations
- Loading and progress states
- Micro-interactions and feedback
- Scroll-driven effects
- Interactive data visualizations
Notes
- Test on lower-end devices
- Always respect prefers-reduced-motion
- Keep animations consistent across the app
- Don't animate everything - be selective
Du fichier au premier essai
Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.
Consulter la source et ses fichiers annexesCe téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.
1. Télécharger le fichier
Télécharger SKILL.mdDepuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/animation-motion-design-mm78no99/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.
Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.
mkdir -p '.skill-downloads/animation-motion-design-mm78no99' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/animation-motion-design-mm78no99/download' --output '.skill-downloads/animation-motion-design-mm78no99/SKILL.md.part' && mv '.skill-downloads/animation-motion-design-mm78no99/SKILL.md.part' '.skill-downloads/animation-motion-design-mm78no99/SKILL.md'2. Vérifier les prérequis
Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.
Aucune section de prérequis reconnue dans ce fichier. Cela ne signifie pas qu’il est autonome : les bibliothèques, outils et accès peuvent être cités ailleurs dans le contenu ou dans le dépôt source.
Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.
3. Charger la skill
Après vérification, copiez le dossier complet dans le projet avec l’une des commandes ci-dessous, puis ouvrez une nouvelle session de l’outil. La commande s’arrête si un dossier du même nom existe déjà : comparez les fichiers avant de le remplacer.
Claude Code
test -f '.skill-downloads/animation-motion-design-mm78no99/SKILL.md' && test -s '.skill-downloads/animation-motion-design-mm78no99/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/animation-motion' && cp -R '.skill-downloads/animation-motion-design-mm78no99' '.claude/skills/animation-motion'Cursor
test -f '.skill-downloads/animation-motion-design-mm78no99/SKILL.md' && test -s '.skill-downloads/animation-motion-design-mm78no99/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/animation-motion' && cp -R '.skill-downloads/animation-motion-design-mm78no99' '.cursor/skills/animation-motion'Codex
test -f '.skill-downloads/animation-motion-design-mm78no99/SKILL.md' && test -s '.skill-downloads/animation-motion-design-mm78no99/SKILL.md' && mkdir -p '.agents/skills' && test ! -e '.agents/skills/animation-motion' && cp -R '.skill-downloads/animation-motion-design-mm78no99' '.agents/skills/animation-motion'OpenSkills
OpenSkills doit déjà être installé. La procédure locale install/read est contrôlée avec OpenSkills 1.5.0, qui exige Node.js ≥ 20.6.0. Aucun slug du catalogue n’est résolu automatiquement.
Installation officielle d’OpenSkillsopenskills install './.skill-downloads/animation-motion-design-mm78no99'openskills read 'animation-motion-design-mm78no99'La lecture doit afficher le contenu du fichier installé et son dossier de base. Elle ne lance ni la skill ni ses dépendances.
Pour un agent qui lit AGENTS.md, synchronisez ensuite l’index. Cette commande modifie AGENTS.md : relisez le diff avant de l’utiliser.
openskills syncMode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.
4. Faire un premier essai
Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :
Lis .skill-downloads/animation-motion-design-mm78no99/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.
Bonnes pratiques React Hook Form
Developpement
Maîtrisez React Hook Form : évitez les anti-patterns, gérez les abonnements, et traitez correctement reset, dirty state et entrées contrôlées.
Migration Emotion vers Mantine
Developpement
Migrer les styled-components Emotion vers des composants Mantine avec style props et modules CSS. Pour convertir .styled.tsx ou supprimer les imports @emotion.
Détecteur de dérive de périmètre
Developpement
Analyse les diffs git par rapport à une intention pour détecter la dérive de périmètre, fichiers non liés et PR trop larges, puis suggère de garder, diviser ou justifier.