Cartes✨ Premium

Tab Content Morph

Panneau d'onglets CSS pur : les panneaux permutent par un crossfade opacity et un glissement translateY+scale synchronisés — morphing fluide en 0,5 s, zéro librairie.

CSSJSTabs

Vous aurez accès à la démo interactive avec un compte gratuit.

Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Cartes comprend 41 effets, dont 6 gratuits. Découvrir la catégorie →

3 exemples d'usage

Fiche produit — Détails / Spécifications / Avis — Tab Content Morph exemple 1

① Fiche produit — Détails / Spécifications / Avis

QuandUne page ou modale produit regroupe trois niveaux d'information : description commerciale, caractéristiques techniques et retours clients — trop pour un défilement linéaire dans un espace contraint.
PourquoiLe crossfade empêche le saut de hauteur brusque habituel des onglets : le contenu entre depuis une légère profondeur, rendant la transition perçue comme naturelle plutôt que mécanique.
RéglagesDurée de transition à 0,4 s (modifier .tab-morph-panel { transition }), couleur active adaptée à la charte produit via --primary, min-height sur .tab-morph-content fixé à la hauteur du panneau le plus haut pour éviter le saut de hauteur.
Article de documentation — Aperçu / Exemple / Code — Tab Content Morph exemple 2

② Article de documentation — Aperçu / Exemple / Code

QuandUn article technique (doc, tutoriel, blog) propose plusieurs lectures d'un même sujet : résumé explicatif, démonstration visuelle et snippet prêt à copier.
PourquoiLes onglets segmentent l'information sans quitter la page ; la transition position crée une hiérarchie visuelle — le contenu « entre en scène » plutôt qu'apparaître brutalement, ce qui guide l'œil vers le nouveau panneau.
RéglagesAmplitude verticale 10 px (translateY) et scale 0,95 donnent l'impression d'un léger zoom avant ; réduisez à 5 px / 0,98 pour un effet plus discret sur du contenu dense.
Widget de métriques — Aujourd'hui / Semaine / Mois — Tab Content Morph exemple 3

③ Widget de métriques — Aujourd'hui / Semaine / Mois

QuandUn tableau de bord SaaS affiche des indicateurs clés (vues, conversions, revenus) selon trois granularités temporelles dans un espace contraint.
PourquoiLe morphing CSS donne l'impression que les chiffres « se replacent » quand on change de période, renforçant la perception d'un tableau de bord vivant — sans canvas ni librairie de graphiques.
RéglagesTransition maintenue à 0,5 s pour un rythme de lecture confortable sur des données chiffrées ; contenu de chaque panneau 100 % libre (texte, sparkline SVG, badge tendance).

Comment ça marche

Tous les panneaux sont empilés via position: absolute; inset: 0 dans un conteneur relatif. À l'état inactif, chaque panneau porte opacity: 0 et transform: translateY(10px) scale(.95) : invisible, décalé de 10 px vers le bas et légèrement rétréci. La classe .active le ramène à opacity: 1; transform: translateY(0) scale(1) — c'est la combinaison crossfade + glissement vertical qui définit le morphing.

La transition repose sur une seule règle CSS : transition: .5s cubic-bezier(.4, 0, .2, 1) (la courbe Material Design « ease-out »). Quand switchTab() déplace la classe .active, le panneau sortant fond et glisse vers le bas pendant que le panneau entrant monte et grossit simultanément — les deux transitions s'exécutent en parallèle sur la même couche GPU, sans aucun reflow du document.

La fonction switchTab(index, btn) est déclarée dans une IIFE. Elle retire .active de tous les boutons via querySelectorAll('.tab-morph-btn') et de tous les panneaux via querySelectorAll('#tabMorphContent .tab-morph-panel'), puis pose la classe sur le bouton cliqué et sur le panneau d'indice correspondant. Les panneaux inactifs ont pointer-events: none : aucune interaction involontaire avec du contenu masqué.

Limite : switchTab est déclarée à l'intérieur de l'IIFE et n'est pas exposée dans window ; les attributs onclick du HTML ne la trouvent pas en contexte global. Pour une utilisation multi-instance ou programmatique, redéfinissez window.switchTab en scopant les sélecteurs sur le .tab-morph-wrapper parent du bouton cliqué (voir section Personnalisation et FAQ).

Accessibilité

  • prefers-reduced-motion : absent — le code ne contient aucune détection de cette préférence OS ; la transition de 0,5 s s'exécute toujours, y compris pour les utilisateurs sensibles au mouvement.
  • Les déclencheurs sont des <button> natifs : focusables au clavier par défaut, activables à la touche Entrée ou Espace.
  • Le patron ARIA tabs est absent : ni role="tablist", ni role="tab" sur les boutons, ni role="tabpanel" ni aria-selected — les lecteurs d'écran ne perçoivent pas la relation onglet/panneau.
  • Les panneaux inactifs ont pointer-events: none : aucune interaction involontaire avec du contenu masqué.
  • Contraste du texte des boutons inactifs (#a5b4fc sur fond #0a0a0f) : ratio ≈ 5,1:1, niveau WCAG AA atteint.

Compatibilité navigateur

L'effet repose uniquement sur des transitions CSS et querySelectorAll — disponibles dans tous les navigateurs depuis 2016. Zéro dépendance externe.

Chrome 60+✓ Complet
Firefox 55+✓ Complet
Safari 12+✓ Complet
Edge 79+✓ Complet
Mobile iOS✓ Complet
Android Chrome✓ Complet

Sans support des transitions CSS, les panneaux permutent instantanément (sans morphing) mais la navigation par onglets reste entièrement fonctionnelle — aucune erreur JS.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
<div class="tab-morph-wrapper">
  <div class="tab-morph-nav">
    <button class="tab-morph-btn active" onclick="switchTab(0, this)">Onglet 1</button>
    <button class="tab-morph-btn" onclick="switchTab(1, this)">Onglet 2</button>
    <button class="tab-morph-btn" onclick="switchTab(2, this)">Onglet 3</button>
  </div>
  <div class="tab-morph-content" id="tabMorphContent">
    <div class="tab-morph-panel active"><!-- Contenu 1 --></div>
    <div class="tab-morph-panel"><!-- Contenu 2 --></div>
    <div class="tab-morph-panel"><!-- Contenu 3 --></div>
  </div>
</div>
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.

Personnaliser

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

Option / propriétéDéfautEffet
--primary #6366f1 Variable CSS racine : couleur d'accent du bouton actif (background + border-color). Remplacez par la couleur brand pour intégrer l'effet dans votre design system.
.tab-morph-panel { transition } 0.5s cubic-bezier(.4, 0, .2, 1) Durée et courbe du morphing. Essayez 0,3 s pour un rendu vif, 0,7 s pour un enchaînement cinématique. La courbe ease-out est celle de Material Design.
translateY(10px) dans .tab-morph-panel 10px Amplitude verticale du glissement d'entrée. Réduisez à 4 px pour un déplacement quasi imperceptible, montez à 20 px pour un effet de profondeur plus marqué.
scale(.95) dans .tab-morph-panel 0.95 Facteur d'échelle du panneau inactif. Descendez à 0,90 pour accentuer le zoom avant d'entrée, remplacez par 1 pour supprimer l'effet de scale.
.tab-morph-content { min-height } 80px Hauteur minimale du conteneur de panneaux. Ajustez à la hauteur du panneau le plus grand pour éviter le saut de mise en page quand les panneaux ont des contenus de tailles très différentes.
.tab-morph-btn { padding } 6px 14px Taille des zones de clic. Augmentez le padding pour respecter la cible tactile minimum de 44 × 44 px recommandée par WCAG 2.5.5.
window.switchTab(index, btn) Redéfinissez cette fonction pour la rendre accessible globalement et scopée par instance (btn.closest('.tab-morph-wrapper')) — indispensable pour plusieurs instances sur la même page ou pour déclencher un changement d'onglet programmatiquement.

FAQ

Dans sa version d'origine, switchTab interroge querySelectorAll('.tab-morph-btn') sans contrainte de portée — plusieurs instances se perturbent mutuellement. Pour en avoir plusieurs, redéfinissez window.switchTab en scopant les sélecteurs sur le wrapper parent : var w = btn.closest('.tab-morph-wrapper'); w.querySelectorAll('.tab-morph-btn').forEach(…). Chaque instance est alors totalement indépendante.
Ajoutez <button class="tab-morph-btn" onclick="switchTab(3, this)">Onglet 4</button> dans .tab-morph-nav et <div class="tab-morph-panel">…</div> dans .tab-morph-content. L'index passé à switchTab correspond à la position du panneau (0-based). Aucune modification du CSS n'est nécessaire — la transition s'applique automatiquement à tout élément .tab-morph-panel.
Non, le code d'origine ne vérifie pas cette préférence. Pour l'ajouter, injectez en CSS : @media (prefers-reduced-motion: reduce) { .tab-morph-panel { transition: none; } }. Les panneaux permutent alors instantanément sans animation — fonctionnel et respectueux des utilisateurs sensibles au mouvement.