Skip to main content
ExodeUI

EXODEUI DESKTOP

A little space for good ideas.

Choose your platform to get the official ExodeUI installer.

Looking for Intel Mac or other builds? Explore the web studio or check all download options.

Prefer the browser? Try for free in your browser →
LanguageEnglish
Navigation5 min read·Updated October 2026·By the ExodeUI team

How to Animate a Hamburger Menu Icon

How to animate a hamburger icon into a close button: the geometry, the timing, pairing it with the menu panel, and the accessibility attributes that must follow.

Direct Summary & Definition

Core Takeaway

The hamburger icon is a state label: three lines mean closed, an X means open. Animate the top and bottom lines into the diagonal strokes by translating and rotating them, and fade or hide the middle line. Keep the transition short and symmetrical, and make sure the button's accessible name and aria-expanded change with the icon, not just the animation.

It is a state indicator, not decoration

Users read the icon to know whether the menu is open. The animation should make the state change obvious without becoming a performance. The most legible transformation is three lines becoming an X, because the shapes map onto each other and the eye can follow the movement.

The geometry that works

Position the top and bottom bars, translate them to the vertical centre, then rotate one by 45 degrees and the other by -45 degrees. The middle bar fades out or scales to zero. Because you are changing transform, the browser can animate it cheaply. Keep the bars the same length so the X is symmetrical.

Timing and symmetry

The two diagonals should arrive together. If one rotates before the other, the icon looks like it is falling apart. Short and even is better than slow and elaborate. Reversing the animation should return the exact original geometry so the closed state is pixel-identical to the start.

Pair it with the panel

The icon change and the menu opening are one event. If the panel slides in from the side, start the icon change at the same moment, not after the panel finishes. If the panel covers the icon, the animation is wasted; keep the close control visible or provide a clear close button inside.

Accessibility comes first

Use a real button with an accessible name that changes between open and close, and keep aria-expanded in sync. The icon itself is decorative, so hide it from assistive technology. When the menu opens, move focus into it or to the first item, trap focus if it behaves like a dialog, and return focus to the button when it closes.

Reduced motion

For reduced motion, swap the icon without rotating it, or use a very short cross-fade. The state change still needs to be clear, so do not remove the visual difference; just remove the travel.

Production Implementation Snippet

Interactive Component Implementation
.icon span {
  transition: transform 180ms ease, opacity 180ms ease;
}

.icon[data-open="true"] span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}

.icon[data-open="true"] span:nth-child(2) {
  opacity: 0;
}

.icon[data-open="true"] span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
  .icon span { transition: opacity 80ms linear; }
}

Key Principles to Remember

  • The icon communicates open or closed, so keep it in sync with state
  • Translate and rotate the outer bars, fade the middle one
  • Both diagonals should land together
  • Start the icon change with the panel, not after it
  • Update aria-expanded and the accessible name with the icon

Frequently Asked Questions

Sources

  1. Disclosure Pattern — W3C WAI-ARIA Authoring Practices
  2. Dialog (Modal) Pattern — W3C WAI-ARIA Authoring Practices
  3. prefers-reduced-motion — MDN Web Docs

Related Guides & Examples

Make the icon and the menu one state.

ExodeUI models open and closed as states with inputs and events in one open .exode file. Try it on the free Community plan.

See interactive examples
Try for free