Cartes✨ Premium

Split Screen Morph

Deux panneaux flex morphent entre 50/50, 70/30 et panneau unique — un bouton ajoute une classe de mode, la transition CSS cubic-bezier gère l'animation sans une ligne de JS d'animation.

CSSFlexLayout

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

🎈

① Éditeur en ligne — Code et aperçu côte à côte

QuandDans un IDE en ligne, un bac à sable interactif ou un tutoriel technique : l'utilisateur agrandit la zone de code ou bascule en aperçu plein cadre selon l'étape en cours.
PourquoiLe mode 50/50 équilibre saisie et rendu ; le mode 70/30 libère de l'espace pour les lignes longues sans masquer l'aperçu ; le mode panneau unique passe l'aperçu en plein écran sans changer de page.
Réglagestransition: .35s cubic-bezier(.4,0,.2,1) sur .split-panel (réaction plus vive pour un outil), fond panel-a #0d1117 (code), fond panel-b #161b22 (preview), libellés : « Code », « 70/30 », « Aperçu ».
🎊

② Documentation technique — Contenu et volet de référence API

QuandUne page de documentation affiche l'article principal à gauche et une référence d'API (paramètres, signatures) à droite — l'utilisateur ferme le volet pour se concentrer sur un passage dense.
PourquoiLe mode 70/30 garde la référence visible sans réduire excessivement l'article ; le mode panneau unique ouvre le texte à la pleine largeur pour la lecture en profondeur.
Réglagestransition: .6s cubic-bezier(.4,0,.2,1) (défaut), fond panel-a #12121c (article), fond panel-b #0e0e1a légèrement distinct (référence), libellés : « 50/50 », « 70/30 », « Plein ».

③ Comparatif de tarifs — Starter vs Pro en regard

QuandUne landing page présente deux plans côte à côte ; l'utilisateur bascule pour isoler le plan qu'il envisage ou revient à la vue comparative avant de choisir.
PourquoiLa transition fluide 50/50 → panneau unique oriente l'attention sans rechargement de page ; démarrer en mode-70-30 côté Pro met visuellement le plan recommandé en avant dès l'arrivée.
Réglagestransition: .8s cubic-bezier(.4,0,.2,1) (transition ample pour une section hero), initialiser le wrapper en mode-70-30 côté plan Pro, palettes contrastées entre les deux panneaux.

Comment ça marche

Le conteneur .split-screen-wrapper est un flex row avec overflow: hidden. Chaque panneau part sur flex: 1 1 0% (50/50 par défaut). La classe .mode-70-30 surcharge les ratios en flex: 7 1 0% et flex: 3 1 0% (7 + 3 = 10, soit 70 % et 30 %). La classe .mode-single collapse le panneau B en flex: 0 1 0% avec min-width: 0; overflow: hidden; font-size: 0 — le navigateur l'écrase à zéro largeur, son contenu disparaît proprement.

Toute la fluidité vient d'une seule règle : transition: .6s cubic-bezier(.4, 0, .2, 1) sur .split-panel. Le navigateur interpole la valeur flex-grow entre les états (CSS Transitions Level 1, propriété interpolable). La courbe cubic-bezier (easing standard Material Design) produit une accélération initiale puis un ralentissement marqué — le mouvement paraît naturel. Aucune boucle JS, aucun requestAnimationFrame — zéro CPU hors de la transition.

setSplitMode(btn, mode) fait trois choses : elle retire .active de tous les .morph-toggle du parent (btn.parentElement.querySelectorAll), l'ajoute au bouton cliqué, puis vide les deux classes de mode du wrapper avant d'en appliquer une nouvelle. L'appel à document.getElementById('splitDemo') est en dur — une seule instance par page avec le code tel quel (voir FAQ pour la multi-instance).

Accessibilité

  • prefers-reduced-motion absent : la transition flex s'anime quel que soit le réglage système. Pour la production, ajouter @media (prefers-reduced-motion: reduce) { .split-panel { transition: none } }.
  • Les boutons sont des <button> natifs avec onclick inline — navigables au clavier (Tab + Entrée ou Espace) sans ajout.
  • Aucun aria-pressed sur les toggles : l'état actif est purement visuel (classe .active). Ajouter aria-pressed="true/false" dans setSplitMode pour les lecteurs d'écran.
  • Pas de role ni d'aria-label sur .split-screen-wrapper — les panneaux doivent porter leurs propres landmarks ou étiquettes si le contenu est significatif.
  • Contraste des labels 'Panel A / Panel B' en blanc sur dégradé violet (#6366f1 → #818cf8) : ratio ≥ 4,5:1 (WCAG AA atteint).

Compatibilité navigateur

Nécessite CSS Flexbox et CSS Transitions — supportés nativement dans tous les navigateurs modernes depuis 2016. Zéro dépendance externe.

Chrome 88+✓ Complet
Firefox 87+✓ Complet
Safari 15+✓ Complet
Edge 88+✓ Complet
Mobile iOS✓ Complet
Android Chrome✓ Complet

Sans CSS Transitions (IE 9 et inférieur), les panneaux changent de largeur instantanément — aucune erreur JS, le changement de mode reste fonctionnel.

Le code

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

index.html — structure
<div class="demo-preview">
  <div class="morph-toggle-group">
    <button class="morph-toggle active" onclick="setSplitMode(this, '50-50')">50/50</button>
    <button class="morph-toggle" onclick="setSplitMode(this, '70-30')">70/30</button>
    <button class="morph-toggle" onclick="setSplitMode(this, 'single')">Seul</button>
  </div>
  <div class="split-screen-wrapper" id="splitDemo">
    <div class="split-panel split-panel-a">Panneau A</div>
    <div class="split-panel split-panel-b">Panneau B</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
transition sur .split-panel .6s cubic-bezier(.4, 0, .2, 1) Durée et courbe de l'animation. Exemple : .35s ease pour une UI réactive, .9s cubic-bezier(.34,1.56,.64,1) pour un rebond élastique.
--primary (var CSS) #6366f1 Couleur des boutons toggle (bordure, fond actif, texte actif). Remplacez par la couleur primaire de votre projet.
flex sur .mode-70-30 .split-panel-a 7 Part du grand panneau en mode asymétrique. 6 = 60/40, 8 = 80/20 — adapter la valeur de .split-panel-b en conséquence.
flex sur .mode-70-30 .split-panel-b 3 Part du petit panneau. La somme doit être cohérente avec .split-panel-a (ex. 8+2, 7+3, 6+4).
gap sur .split-screen-wrapper 4px Gouttière entre les deux panneaux. 0 pour un joint net, 12px pour un espacement aéré.
border-radius sur .split-screen-wrapper 8px Arrondi du conteneur. 0 pour plein bleed, 16px pour une carte ou une modale.
setSplitMode(btn, mode) Appel externe depuis n'importe quel code : déclenche un changement de mode depuis un scroll, un timer ou une interaction clavier sans toucher aux boutons intégrés.

FAQ

Ajoutez deux règles CSS : .split-screen-wrapper.mode-30-70 .split-panel-a { flex: 3 1 0% } et .mode-30-70 .split-panel-b { flex: 7 1 0% }. Ajoutez un bouton avec onclick="setSplitMode(this, '30-70')", puis étendez la condition dans setSplitMode : '30-70' === t ? o.classList.add('mode-30-70') : ….
Oui. Remplacez <div class="split-panel-a">Panel A</div> par n'importe quel HTML. Ajoutez min-width: 0 sur les panneaux si le contenu est rigide (tableaux, éditeurs mono-espace) pour autoriser la réduction en dessous de sa taille naturelle — la propriété est déjà présente sur .mode-single .split-panel-b et sert de modèle.
setSplitMode cible getElementById('splitDemo') en dur. Pour plusieurs instances, renommez chaque wrapper (splitDemo2, etc.) et créez une variante setSplitModeById(btn, mode, id) qui reçoit l'id en paramètre, ou lisez l'id depuis un attribut data-target sur le bouton (btn.dataset.target).