Morphing Hamburger
Trois traits CSS pivotent vers un X avec inertie back-ease — l'indicateur d'état ouvert/fermé le plus reconnu de l'UI mobile.
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. Navigation comprend 36 effets, dont 4 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
L'effet repose sur trois <span class="line"> positionnés en absolu au centre d'un conteneur 36×36 px en flexbox. À l'état hamburger, les traits 1 et 3 sont écartés verticalement via translateY(±8px) ; le trait 2 est délibérément plus court (18 px contre 24 px) — une asymétrie discrète qui donne du caractère à l'icône au repos.
La transformation est entièrement pilotée par CSS : quand la classe .morphed est posée sur le conteneur, les traits 1 et 3 reviennent à Y=0 puis rotate(±45deg) pour former un X, tandis que le trait 2 s'efface via width: 0 et opacity: 0. Aucun calcul JS n'est impliqué dans le rendu.
La courbe de transition cubic-bezier(.68, -.55, .27, 1.55) est un back ease-out : les traits dépassent légèrement l'angle cible (overshoot) avant de revenir à la position finale. Cet effet d'inertie mécanique — invisible sur une transition linéaire — renforce la perception de poids et de réponse sans recourir à JS. La durée de 0,4 s laisse l'œil suivre le mouvement sans latence perçue.
Le JavaScript se limite à un unique classList.toggle('morphed') déclenché au clic sur l'élément. Si l'utilisateur clique avant la fin de la transition, le navigateur reprend l'animation depuis l'état intermédiaire courant et l'inverse — comportement natif, aucune gestion d'état manuelle requise.
Accessibilité
- prefers-reduced-motion absent : aucune règle
@media (prefers-reduced-motion: reduce)n'est présente dans le code. La transition s'exécute toujours, quel que soit le paramètre OS. À ajouter si nécessaire :.morphing-hamburger .line { transition: none; }dans la media query. - L'élément déclencheur est un
<div>avec handler JS, pas un<button>natif — non focusable au clavier par défaut. Ajoutertabindex="0"et un gestionnairekeydown(Entrée/Espace) pour la conformité WCAG 2.1. - Aucun
aria-expandedprésent : les lecteurs d'écran ne peuvent pas connaître l'état ouvert/fermé. Alterneraria-expanded="false"/"true"au clic dans le handler. - Aucun
aria-label: le contrôle n'a pas de nom accessible. Ajouteraria-label="Ouvrir le menu"mis à jour dynamiquement à chaque toggle. - Contraste des traits (
#fffsur fond#0a0a0f) : ratio > 21:1 — conforme WCAG AA et AAA sans condition.
Compatibilité navigateur
Nécessite CSS Transitions et classList.toggle — disponibles dans tout navigateur moderne depuis 2014.
Sans JavaScript, l'icône reste figée en état hamburger — aucun style cassé, aucune erreur. Sans support des transitions CSS (IE9 et antérieurs), le passage hamburger → X s'effectue instantanément sans animation.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="morphing-hamburger" id="morphingHamburger">
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
</div>
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éfaut | Effet |
|---|---|---|
| background (sur .morphing-hamburger .line) | #fff | Couleur des traits. Passez en couleur brand ou en currentColor pour hériter de la couleur de texte du parent. |
| width (sur .line) | 24px | Largeur des traits 1 et 3. Ajustez en parallèle le trait 2 (.line:nth-child(2), 18 px) pour conserver le ratio asymétrique — ex. 20 px / 15 px pour une icône compacte. |
| height (sur .line) | 2px | Épaisseur des traits. 3 px pour un look bold, 1 px pour un style ultra-fin. |
| transition (sur .line) | .4s cubic-bezier(.68,-.55,.27,1.55) | Durée et courbe d'animation. Réduisez à .2s pour une réponse vive, ou remplacez la courbe par ease-in-out pour supprimer l'overshoot et obtenir une transition sobre. |
| translateY (lignes 1 et 3) | ±8px | Écart vertical entre les traits en état hamburger. Réduisez à ±6 px pour une icône compacte, augmentez à ±10 px pour une icône plus aérée. |
| width / height (sur .morphing-hamburger) | 36px / 36px | Taille du conteneur et de la zone cliquable. Passez à 44 px minimum pour respecter les recommandations WCAG sur la taille de cible tactile (2,75 rem). |
| border-radius (sur .line) | 2px | Arrondi des extrémités. 0 pour des traits carrés nets, 4 px pour un look doux et arrondi. |
FAQ
<div class="morphing-hamburger" id="morphingHamburger"> par un <button> avec les mêmes classe et id. Ajoutez background: none; border: none; padding: 0; cursor: pointer; dans le CSS pour neutraliser les styles par défaut. Le JS toggle reste identique ; mettez à jour aria-label et aria-expanded au clic pour la conformité WCAG.classList.toggle('morphed') gère l'état graphique de l'icône. Dans le même handler, déclenchez l'ouverture de votre menu : nav.classList.toggle('open'), une transition de hauteur ou un transform: translateX. L'icône et le menu partagent le même toggle et restent toujours synchronisés sans état supplémentaire.