SPB Git

spb/svgarden Public

SVGarden — searchable bank of 74 self-contained SVG+CSS animation snippets (svgarden.dev)

HTML 79.2% Astro 10.3% JavaScript 6% CSS 3.7% Shell 0.8%
2.8 KB · 76 lines html
Raw Blame History
1<!--2  ============================================================3  SVGarden — https://www.svgarden.dev4  Author : Simon-Pierre Boucher5  Contact: contact@spboucher.ai6  File   : snippets/hover/icon-morph-menu.html7  Desc   : Hamburger menu morphing into an X on hover8  ============================================================9-->10<!--svgarden11title: Menu ⇄ X morph12slug: icon-morph-menu13category: hover14tags: [hover, menu, hamburger, morph]15difficulty: intermediate16techniques: [transition, translate-then-rotate, opacity, transform-origin]17how_it_works: >18  Three <line> elements fake a path morph with plain transforms: on hover the19  top and bottom bars first translate to the vertical center, then rotate ±45°20  to form the X, while the middle bar fades and shrinks away. The two-step feel21  comes from transitioning translate and rotate with the same duration but22  letting the rotation visually dominate — order the transforms translate-first23  or the bars swing along arcs instead of collapsing cleanly.24customizable:25  - { var: "--sg-color",    label: "Color", type: color, default: "#7F77DD" }26  - { var: "--sg-size",     label: "Size",  type: range, min: 24, max: 96, default: 48, unit: px }27  - { var: "--sg-duration", label: "Speed", type: range, min: 0.1, max: 1, step: 0.05, default: 0.3, unit: s }28created: 2026-08-1029-->30<button class="sg-icon-morph-menu" type="button" aria-label="Menu" style="--sg-color:#7F77DD; --sg-size:48px; --sg-duration:0.3s;">31  <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">32    <line class="sg-icon-morph-menu-top" x1="4" y1="7" x2="20" y2="7" />33    <line class="sg-icon-morph-menu-mid" x1="4" y1="12" x2="20" y2="12" />34    <line class="sg-icon-morph-menu-bot" x1="4" y1="17" x2="20" y2="17" />35  </svg>36</button>37<style>38  .sg-icon-morph-menu {39    appearance: none;40    border: 1px solid var(--sg-color);41    border-radius: 10px;42    padding: 0;43    background: transparent;44    cursor: pointer;45    width: var(--sg-size);46    height: var(--sg-size);47    display: inline-grid;48    place-items: center;49  }50  .sg-icon-morph-menu svg {51    width: 70%;52    height: 70%;53  }54  .sg-icon-morph-menu line {55    stroke: var(--sg-color);56    stroke-width: 2.4;57    stroke-linecap: round;58    transform-box: fill-box;59    transform-origin: center;60    transition: transform var(--sg-duration) ease, opacity var(--sg-duration) ease;61  }62  .sg-icon-morph-menu:hover .sg-icon-morph-menu-top,63  .sg-icon-morph-menu:focus-visible .sg-icon-morph-menu-top {64    transform: translateY(5px) rotate(45deg);65  }66  .sg-icon-morph-menu:hover .sg-icon-morph-menu-bot,67  .sg-icon-morph-menu:focus-visible .sg-icon-morph-menu-bot {68    transform: translateY(-5px) rotate(-45deg);69  }70  .sg-icon-morph-menu:hover .sg-icon-morph-menu-mid,71  .sg-icon-morph-menu:focus-visible .sg-icon-morph-menu-mid {72    transform: scaleX(0.1);73    opacity: 0;74  }75</style>76