Toggle Morph
Un interrupteur dont la pastille, en glissant, s'allonge de 28 à 44 px et devient rectangle arrondi à mi-course avant de redevenir ronde, comme une goutte qui s'étire, avec un rebond, un passage du violet au rose et un libellé d'état mis à jour. Un vrai interrupteur au sens des lecteurs d'écran (bouton à rôle switch, état coché ou non), utilisable au clavier ; pastille qui change de côté sans s'étirer si l'utilisateur réduit les animations.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Liquid comprend 31 effets, dont 6 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Le rail .toggle-morph est un <button role="switch"> de 80 × 40 px (fond blanc à 10 %, bordure de 2 px, coins de 20 px) ; la pastille .toggle-morph-knob de 28 px y est posée à 4 px du bord gauche. Au clic, le script bascule .active : la pastille glisse à 44 px avec transition: .5s cubic-bezier(.68, -.55, .27, 1.55), qui la fait reculer un peu puis dépasser sa place, et son dégradé passe de violet à rose ; le rail se teinte de violet. En même temps, le script relance la classe .morphing, qui joue l'animation fx0410-knob en 0,5 s : de 30 % à 60 % du trajet, la pastille mesure 44 px de large et ses coins passent à 10 px, puis elle redevient un rond de 28 px à l'arrivée.
Deux mouvements se superposent donc : la position, en transition, et la forme, en animation. C'est cette forme qui s'allonge pendant le trajet qui distingue l'effet d'un interrupteur ordinaire : l'œil voit une matière qui se déplace plutôt qu'un rond qui change de côté. Pour qu'un double clic rapide relance l'étirement au lieu de le laisser se finir, le script retire la classe, force le navigateur à en tenir compte (void knob.offsetWidth), puis la remet. La classe est retirée à la fin de l'animation (animationend).
L'état est porté par aria-checked (true ou false), que les lecteurs d'écran annoncent « activé » ou « désactivé ». Le libellé visible sous le rail vient des attributs data-on et data-off du bouton (« Activé » / « Désactivé ») ; il est masqué aux lecteurs d'écran, qui ont déjà l'état. Le nom du bouton, aria-label="Interrupteur", est à remplacer par ce qu'il commande : « Disponible pour une course », « Veilleuse ». Le script parcourt tous les .fx-0410-root .toggle-morph de la page.
Accessibilité
- Clavier : mesuré dans Chromium 151 et Firefox 153, Tab atteint l'interrupteur, Entrée comme Espace le basculent, et
aria-checkedsuit. Anneau de focus rose de 2 px, décalé de 3 px, au clavier seulement. Dans Safari, Tab ne s'arrête sur les boutons que si le réglage clavier le demande (ou avec Option+Tab). - Lecteurs d'écran : annoncé « Interrupteur, bouton bascule, désactivé » puis « activé ». Donnez-lui un nom qui dit ce qu'il commande, sans l'état dedans (« Veilleuse », pas « Activer la veilleuse »).
- Mouvement réduit : sous
prefers-reduced-motion: reduce, la pastille n'a plus de transition de position et le script n'ajoute pas.morphing: elle change de côté d'un coup, sans s'étirer. Mesuré dans les trois moteurs : aucune image intermédiaire pour la pastille. - Couleur : l'état se lit aussi par la position de la pastille et par le libellé, pas seulement par le passage au rose. Le libellé blanc à 50 % sur fond sombre reste au-dessus de 4,5:1.
Compatibilité navigateur
CSS (transitions, @keyframes) + 1,1 Ko de JavaScript, aucune dépendance. Mesuré image par image dans Chromium 151, Firefox 153 et WebKit 26 : même trajet, même étirement à mi-course, même arrêt sous mouvement réduit. role="switch" est lu par VoiceOver, NVDA et TalkBack ; un lecteur plus ancien l'annonce comme une case à cocher, avec le même état.
Sans JavaScript, l'interrupteur reste désactivé et ne bascule pas : si le réglage est important, doublez-le d'une vraie case à cocher dans un formulaire. Sans animations CSS, la pastille change de côté sans s'étirer.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0410-root">
<div class="toggle-morph-container">
<button type="button" class="toggle-morph" role="switch" aria-checked="false"
aria-label="Interrupteur" data-on="Activé" data-off="Désactivé">
<span class="toggle-morph-knob"></span>
</button>
<span class="toggle-morph-state" aria-hidden="true">Désactivé</span>
</div>
</div>
Paiement unique, sans abonnement — le code est à toi pour toujours
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Nom accessible (HTML — aria-label) |
« Interrupteur » | Nommez ce que l'interrupteur commande : « Veilleuse », « Notifications par SMS ». Ou reliez-le à un texte visible avec aria-labelledby. |
Libellés d'état (HTML — data-on / data-off) |
« Activé » / « Désactivé » | Les mots du réglage : « Ouverte » / « Fermée », « Disponible » / « En pause ». Le script les relit à chaque clic. Mettez le libellé de départ dans .toggle-morph-state. |
Étirement (CSS — @keyframes fx0410-knob) |
44 px de large et coins de 10 px de 30 % à 60 % du trajet | 52 px donnent une goutte plus longue ; ne dépassez pas la largeur du rail moins 8 px. 30%, 60% règle quand elle s'étire : 20%, 70% l'allonge plus tôt et plus longtemps. |
Rebond et durée (CSS — transition: .5s cubic-bezier(.68, -.55, .27, 1.55) de la pastille, .5s de .morphing) |
0,5 s, recul puis dépassement | Gardez la même durée aux deux, sinon la pastille s'étire après être arrivée. .35s ease donne un interrupteur plus vif, sans rebond. |
Couleurs (CSS — rail, pastille et règles .active) |
pastille violet #a855f7 → #7c3aed, puis rose #ec4899 → #a855f7 |
Une couleur neutre au repos et une couleur franche une fois activé rendent l'état lisible d'un coup d'œil, comme le gris puis vert du taxi. |
FAQ
aria-checked : toggle.addEventListener('click', function () { var on = toggle.getAttribute('aria-checked') === 'true'; /* enregistrer on */ });. Placez ce code après le script de l'effet, qui met l'état à jour en premier. Pour démarrer activé, mettez class="toggle-morph active", aria-checked="true" et le libellé de data-on dans le HTML.role="switch" sur un <button> donne les deux : le comportement clavier natif du bouton et l'annonce « activé / désactivé ». Si votre réglage fait partie d'un formulaire envoyé d'un bloc, une vraie <input type="checkbox"> stylée reste le meilleur choix.aria-checked annonce déjà « activé » ou « désactivé ». Laisser aussi le libellé lisible ferait entendre l'état deux fois, et dans des mots différents (« Disponible », puis « activé »). Le libellé reste pour les yeux ; l'état pour l'oreille vient de l'attribut.