Transitions✨ Premium

Shared Element

Un seul élément, jamais copié, glisse d'un emplacement à l'autre en 0,8 s avec un dépassement de 17 px avant de se poser, grossit de 15 % et passe du rose au violet : l'objet reste le même pendant que sa place change. Une transition CSS sur transform, posée sur deux positions connues d'avance — 0,6 Ko de JavaScript pour la bascule, arrivée directe si l'utilisateur réduit les animations.

CSSSharedPremium

Mis à jour le

Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Transitions comprend 52 effets, dont 9 gratuits. Découvrir la catégorie →

3 exemples d'usage

Pion qui avance de deux cases — cours d'échecs en ligne pour débutants — Shared Element exemple 1

① Pion qui avance de deux cases — cours d'échecs en ligne pour débutants

QuandLeçon sur les ouvertures : l'élève clique sur l'échiquier et voit le pion blanc partir de e2 et arriver en e4, la case de départ restant surlignée en jaune.
PourquoiLa pièce glisse d'une case à l'autre au lieu de disparaître et réapparaître : l'élève la suit des yeux et comprend qu'un pion peut avancer de deux cases à son premier coup.
RéglagesTrajet vertical (translateY(-80px), deux cases de 40 px) au lieu de horizontal ; pion de 34 px ivoire qui prend un halo doré en e4 ; échiquier de 320 px dessiné en conic-gradient, pièces en caractères Unicode.
Commande qui passe en « Expédiée » — back-office d'une boutique de céramiste — Shared Element exemple 2

② Commande qui passe en « Expédiée » — back-office d'une boutique de céramiste

QuandMardi, jour d'envoi : l'artisane marque la commande n° 1182 (vase en grès émaillé) comme expédiée, la carte quitte la colonne « En préparation » pour « Expédiée ».
PourquoiLa carte voyage d'une colonne à l'autre : l'artisane voit ce qui a changé de statut sans chercher, et passe de l'orange au vert en route.
RéglagesL'élément devient une carte de 216 × 70 px (coins de 10 px, texte aligné à gauche) ; colonnes de 240 × 300 px ; trajet de 260 px, grossissement réduit à 1,04 ; dégradé orange #d97706 → #f59e0b puis vert #15803d → #22c55e.
Opérateur changé d'équipe — planning d'une usine en 3 × 8 — Shared Element exemple 3

③ Opérateur changé d'équipe — planning d'une usine en 3 × 8

QuandJeudi, le chef d'atelier comble le poste vacant de nuit : le badge du remplaçant R. Diallo quitte l'équipe du matin et traverse celle de l'après-midi.
PourquoiLe même badge qui se déplace évite de croire à un doublon ou à une suppression : on suit le mouvement de la personne d'une équipe à l'autre.
RéglagesTrois colonnes de 140 px, l'élément partagé ne s'arrête que dans la première et la dernière (trajet de 312 px) ; badge en pilule de 120 × 44 px, jaune « matin » puis indigo « nuit » ; dépassement conservé, marges élargies pour qu'il reste dans le cadre.

Comment ça marche

La scène .shared-container mesure 300 × 200 px et range côte à côte deux emplacements .shared-slot de 110 × 130 px, bordés de pointillés, à 30 px d'écart. L'élément partagé .shared-ball (rond de 60 px, dégradé #e11d48 → #f43f5e, ombre rose) n'appartient à aucun des deux : il est en position absolue dans la scène, à 25 px du bord gauche. Toute la zone .shared-trigger est un bouton (role="button", tabindex="0") : un clic, Entrée ou Espace bascule la classe .active sur la scène et met à jour aria-pressed. Chaque zone de la page a son propre écouteur, rien n'est exposé sur window.

Avec .active, l'élément reçoit transform: translateX(190px) scale(1.15) (190 px = 300 px de scène − 85 − 25), un dégradé violet #7c3aed → #a78bfa et une ombre violette. La transition de 0,8 s suit cubic-bezier(.34, 1.56, .64, 1), une courbe qui dépasse 1 : mesuré toutes les 100 ms dans Chromium 151 et Firefox 153, l'élément passe à 116, 176, 214 puis 228 px, dépasse sa place de 17 px vers 400-500 ms, revient et se pose à 211 px à 800 ms. Le déplacement passe par transform, que le navigateur compose sans recalculer la mise en page ; l'ombre change de couleur pendant le trajet, mais le dégradé, qui ne s'interpole pas, bascule dès le clic. Un second clic joue le chemin inverse avec le même rebond.

C'est une technique à la main : les deux positions sont connues d'avance et écrites dans le CSS, l'élément ne change jamais de parent dans le DOM. L'API View Transitions fait autre chose : elle photographie la page avant et après un changement du DOM et interpole entre les deux images (voir View Transitions Page Reveal). Ici, aucun instantané : c'est le vrai élément qui se déplace, avec son texte, ses états de survol et son focus, et cela fonctionne dans tous les navigateurs qui connaissent les transitions CSS. La contrepartie : si l'arrivée dépend de la mise en page (une carte qui change de liste), il faut mesurer les positions en JavaScript, comme le décrit la FAQ.

Accessibilité

  • Clavier : la zone est un bouton atteignable à la tabulation ; Entrée et Espace basculent comme le clic (mesuré dans Chromium et Firefox), aria-pressed passe à true, et un contour blanc de 2 px marque le focus. Son aria-label (« Déplacer l'élément vers l'autre zone ») dit l'action ; remplacez-le par la vôtre (« Marquer la commande comme expédiée »).
  • Mouvement réduit : sous prefers-reduced-motion, la transition est retirée et l'élément est dans l'autre zone dès l'image suivante — mesuré : 211 px 60 ms après le clic, sans dépassement.
  • Changement d'état : le déplacement se voit mais ne s'entend pas. Si l'emplacement porte un sens (statut, équipe), écrivez-le aussi dans le texte de l'élément ou annoncez-le dans une zone aria-live : un lecteur d'écran ne perçoit que aria-pressed.
  • Contraste : « GO » en blanc donne 4,7:1 sur le rouge #e11d48 mais 3,7:1 sur le rose clair et 2,7:1 sur #a78bfa ; gardez un texte court et gras, ou foncez la fin des dégradés. Les étiquettes des zones (blanc à 30 %, 2,6:1) et l'indication du bas (3,1:1) sont décoratives : ne leur confiez pas d'information.

Compatibilité navigateur

Transitions CSS sur transform, box-shadow et background, et une quinzaine de lignes de JavaScript, aucune dépendance. Mesuré dans Chromium 151, Firefox 153 et WebKit 26 : même trajet de 190 px, même dépassement, même arrivée à l'échelle 1,15, même retour au second clic ; arrivée directe sous mouvement réduit. Seul le dégradé de fond ne s'interpole pas (aucun navigateur n'anime background-image) : il bascule au départ.

Chrome 51+✓ Complet
Firefox 50+✓ Complet
Safari 10+✓ Complet
Edge 79+✓ Complet
Mobile iOS 10+✓ Complet, au toucher
Android Chrome 51+✓ Complet, au toucher

Sans JavaScript, l'élément reste dans la première zone et le clic ne fait rien. Avec le mouvement réduit, il change de zone sans trajet. Sans transitions CSS (navigateurs très anciens), il saute d'une zone à l'autre.

Le code

Structure HTML à coller dans votre page (le CSS + JS sont inclus avec Premium) :

index.html — structure
<div class="shared-root">
  <div class="shared-trigger" role="button" tabindex="0" aria-pressed="false" aria-label="…">
    <div class="shared-container">
      <div class="shared-slot"><span class="shared-slot-label">Zone A</span></div>
      <div class="shared-slot"><span class="shared-slot-label">Zone B</span></div>
      <div class="shared-ball">GO</div>
    </div>
    <span class="shared-hint">Cliquez pour basculer</span>
  </div>
</div>
Débloquer le code complet — 9,90 € TTC/mois

Le code complet HTML + CSS + JS de Shared Element, prêt à coller — et les 840 effets. Ou 299 € TTC une fois, accès à vie.

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Trajet (CSS — translateX(190px)) 190 px vers la droite Calculé pour la scène de 300 px. translateY(-80px) donne un trajet vertical ; translate(190px, 40px) une diagonale. Le dépassement vaut environ 9 % du trajet : prévoyez la marge correspondante au bord.
Courbe et durée (CSS — transition: .8s cubic-bezier(.34, 1.56, .64, 1)) 0,8 s, dépassement puis retour cubic-bezier(.2, .8, .2, 1) arrive sans dépasser ; 0,5 s pour un déplacement court, au-delà de 1 s le geste paraît lent.
Grossissement à l'arrivée (CSS — scale(1.15)) ×1,15 scale(1) garde la taille ; un élément qui change d'importance (sélectionné, mis en avant) peut aller à 1,3.
Couleurs (CSS — background et box-shadow de .shared-ball) rose #e11d48 → violet #7c3aed L'ombre glisse d'une couleur à l'autre, le dégradé bascule au départ. Pour une couleur qui change en route, utilisez background-color uni (il s'interpole).
Forme de l'élément (CSS — .shared-ball) rond de 60 px Une carte, un badge, une image : changez width, height et border-radius, puis recalculez le trajet pour qu'il arrive dans le second emplacement.

FAQ

Non, ni rien d'autre de l'API View Transitions. Cette API (document.startViewTransition, view-transition-name) photographie la page avant et après un changement du DOM et anime entre les deux images ; c'est ce que fait View Transitions Page Reveal (fx-0786). Shared Element anime le vrai élément avec une transition CSS sur transform, entre deux positions écrites dans la feuille de style. Avantages : fonctionne partout, garde le texte sélectionnable et le focus pendant le trajet. Limite : l'élément ne change pas de parent, les positions doivent être connues.
Avec la technique FLIP : mesurez sa position (var first = el.getBoundingClientRect()), déplacez-le dans le DOM (colonneB.appendChild(el)), mesurez la nouvelle (last), appliquez sans transition el.style.transform = 'translate(' + (first.left - last.left) + 'px, ' + (first.top - last.top) + 'px)' pour le remettre visuellement à son point de départ, puis, à l'image suivante (requestAnimationFrame), remettez transform à zéro avec la transition de cet effet. L'élément glisse vers sa nouvelle place, avec le même dépassement.
Le fond est un dégradé (background-image), et les navigateurs n'interpolent pas un dégradé vers un autre : la valeur bascule au début de la transition. L'ombre, elle, est une couleur simple et passe du rose au violet pendant tout le trajet. Pour une couleur qui change en route, remplacez le dégradé par background-color, ou superposez un pseudo-élément ::before violet dont l'opacité passe de 0 à 1.