Retour au blog

Framer Motion pour landing pages : guide complet des animations

Publié le 20 mars 2026·6 min read

Les landing pages statiques convertissent. Les landing pages animées convertissent mieux. Un mouvement subtil guide le regard, renforce la hiérarchie visuelle et rend les interactions intentionnelles plutôt que brusques. Framer Motion est la bibliothèque d'animation de référence pour React — ce guide couvre les cinq patterns d'animation essentiels pour vos landing pages.

Pourquoi Framer Motion ?

Les animations CSS gèrent bien les transitions simples. Mais dès que vous avez besoin de révélations au scroll, de séquences stagger orchestrées, d'animations de layout ou d'interactions gestuelles, le CSS pur devient ingérable. Framer Motion offre une API déclarative qui s'intègre naturellement avec le modèle composant de React :

npm install motion

Depuis la v11, le package est publié sous le nom motion (anciennement framer-motion). Importez depuis "motion/react" dans les nouveaux projets :

import { motion } from "motion/react";

1. Animations d'entrée

Le pattern le plus courant : faire apparaître les éléments en fondu avec un glissement. Utilisez les props initial et animate sur les composants motion :

"use client";

import { motion } from "motion/react";

const ease = [0.16, 1, 0.3, 1] as const;

export function HeroHeadline() {
  return (
    <motion.h1
      initial={{ opacity: 0, y: 32 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.7, ease }}
      className="text-5xl font-bold tracking-tight"
    >
      Expédiez plus vite avec des sections prêtes à l'emploi
    </motion.h1>
  );
}

La courbe de Bézier [0.16, 1, 0.3, 1] produit un effet rapide-en-entrée, lent-en-sortie popularisé par Apple. Le rendu est vif sans être abrupt — bien meilleur que la courbe ease par défaut pour les entrées d'interface.

Utilisez ce pattern pour les sections hero où le titre, le sous-titre et le bouton CTA s'animent en séquence.

2. Animations déclenchées au scroll

Les animations d'entrée se déclenchent au montage. Pour les sections sous le fold, vous voulez des animations déclenchées quand l'utilisateur scrolle. Le whileInView de Framer Motion gère ça :

<motion.div
  initial={{ opacity: 0, y: 24 }}
  whileInView={{ opacity: 1, y: 0 }}
  transition={{ duration: 0.6, ease: [0.16, 1, 0.3, 1] }}
  viewport={{ once: true, margin: "-100px" }}
>
  <h2>Des fonctionnalités qui comptent</h2>
  <p>Tout ce qu'il faut pour expédier une landing page en heures, pas en semaines.</p>
</motion.div>

Points clés :

  • viewport.once: true — l'animation se déclenche une seule fois et reste dans son état final. Sans ça, remonter dans la page la remet à zéro, ce qui fait amateur.
  • viewport.margin: "-100px" — déclenche l'animation 100px avant que l'élément entre dans le viewport. L'animation est déjà en cours quand l'utilisateur la voit.

C'est le pattern standard pour les sections features et les blocs de témoignages.

3. Stagger des enfants

Une grille de cartes features qui s'anime d'un coup paraît plate. Les faire apparaître en décalé — chaque enfant 80ms après le précédent — crée un rythme visuel. Utilisez des variants avec staggerChildren :

"use client";

import { motion } from "motion/react";

const containerVariants = {
  hidden: {},
  visible: {
    transition: {
      staggerChildren: 0.08,
    },
  },
};

const itemVariants = {
  hidden: { opacity: 0, y: 20 },
  visible: {
    opacity: 1,
    y: 0,
    transition: { duration: 0.5, ease: [0.16, 1, 0.3, 1] },
  },
};

export function FeaturesGrid({ features }: { features: { title: string; description: string }[] }) {
  return (
    <motion.div
      variants={containerVariants}
      initial="hidden"
      whileInView="visible"
      viewport={{ once: true, margin: "-80px" }}
      className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3"
    >
      {features.map((feature) => (
        <motion.div
          key={feature.title}
          variants={itemVariants}
          className="rounded-2xl border border-border bg-card p-6"
        >
          <h3 className="text-lg font-semibold">{feature.title}</h3>
          <p className="mt-2 text-muted-foreground">{feature.description}</p>
        </motion.div>
      ))}
    </motion.div>
  );
}

Le parent définit l'orchestration (staggerChildren), chaque enfant définit sa propre animation (itemVariants). Le whileInView du parent déclenche le conteneur et tous les enfants en séquence. Pas de useEffect, pas d'IntersectionObserver — juste des props déclaratives.

4. Transitions de page

Les applications single-page peuvent animer les transitions entre routes avec AnimatePresence. Dans Next.js App Router, enveloppez le contenu de vos pages dans un AnimatePresence au niveau du layout :

"use client";

import { AnimatePresence, motion } from "motion/react";
import { usePathname } from "next/navigation";

export function PageTransition({ children }: { children: React.ReactNode }) {
  const pathname = usePathname();

  return (
    <AnimatePresence mode="wait">
      <motion.div
        key={pathname}
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        transition={{ duration: 0.25 }}
      >
        {children}
      </motion.div>
    </AnimatePresence>
  );
}

Le prop mode="wait" s'assure que la page sortante disparaît complètement avant que la page entrante apparaisse. Sans lui, les deux pages se rendent simultanément pendant la transition, causant des sauts de layout.

Attention : les transitions de page dans App Router nécessitent des composants clients au niveau du layout, ce qui fait perdre les bénéfices du streaming des Server Components. Utilisez ce pattern de manière sélective — pour les sites marketing où chaque page est légère, pas pour les tableaux de bord riches en données.

5. Effets hover

Les éléments interactifs doivent répondre au survol et au clic. Les props whileHover et whileTap de Framer Motion rendent ça trivial :

<motion.button
  whileHover={{ scale: 1.03 }}
  whileTap={{ scale: 0.97 }}
  transition={{ type: "spring", stiffness: 400, damping: 17 }}
  className="rounded-xl bg-primary px-6 py-3 text-lg font-semibold text-primary-foreground"
>
  Commencer
</motion.button>

La physique de ressort produit un rebond qui paraît naturel. Les valeurs stiffness: 400, damping: 17 donnent un rendu rapide et réactif sans oscillation excessive. Pour les cartes, combinez le scale au hover avec un léger effet de lévitation :

<motion.div
  whileHover={{ y: -4, boxShadow: "0 12px 24px rgba(0,0,0,0.1)" }}
  transition={{ duration: 0.2 }}
  className="rounded-2xl border border-border bg-card p-6"
>
  {/* contenu de la carte */}
</motion.div>

Conseils de performance

  • Utilisez uniquement transform et opacity. Framer Motion anime ces propriétés sur le thread compositor GPU par défaut. Animer width, height ou background-color déclenche un layout ou un repaint — les deux sont plus lents.
  • Ajoutez will-change: transform sur les éléments avec des animations complexes. Framer Motion le fait automatiquement pour les composants motion, mais vérifiez dans DevTools si vous constatez du jank.
  • viewport.once: true n'est pas qu'une question d'UX — ça déconnecte aussi l'IntersectionObserver après le déclenchement, réduisant la charge runtime sur les pages avec beaucoup de scroll.
  • Chargez les sections animées en lazy sous le fold avec next/dynamic pour que le code d'animation ne soit pas dans le bundle initial.

Des sections animées prêtes à l'emploi

Écrire le code d'animation from scratch pour chaque section prend du temps. Le catalogue Incubator inclut 844+ variantes de sections — heroes, grilles de features, témoignages, tables de pricing, CTAs et plus — beaucoup avec les animations Framer Motion déjà câblées. Parcourez les sections hero et les sections features pour voir les entrées au scroll, les grilles stagger et les effets hover en action. Copiez le code, ajustez le contenu, expédiez.

VA

Victor Aubague

Développeur & créateur d'Incubator

Développeur full-stack spécialisé en React, Next.js et TypeScript. J'ai créé Incubator pour aider les développeurs à livrer de belles interfaces plus rapidement — tous les composants sont issus de vrais projets clients et de code en production.

LinkedIn
Framer Motion pour landing pages : guide complet des animations — Incubator