Navigation✨ Premium

Hamburger Menu

Three CSS bars slide and rotate in 300 ms to form a close cross — no dependencies, a single class toggle.

CSSToggle

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Navigation has 36 effects, including 4 free. Explore the category →

3 usage examples

Mobile header — Responsive navigation menu — Hamburger Menu example 1

① Mobile header — Responsive navigation menu

WhenThe user opens the navigation on mobile — the header switches from hamburger to close icon as the link panel slides open.
WhyThe visual feedback is immediate and universal: the cross signals the menu is open and a click will close it, with no extra text or ambiguity.
SettingsStandard size (30×24 px), 3 px bars, white or brand accent color, 300 ms duration.
Side panel — Admin dashboard — Hamburger Menu example 2

② Side panel — Admin dashboard

WhenIn a compact layout where the sidebar can collapse to free space — the hamburger button in the top bar controls the side panel.
WhyThe hamburger/cross icon is universally recognized as a panel controller; the 300 ms transition visually confirms the state change without interrupting the reading flow.
Settings4 px bars, color matching the admin theme (e.g. #94a3b8), 200 ms duration for a snappier perceived response.
Mobile audio player — Settings overlay button — Hamburger Menu example 3

③ Mobile audio player — Settings overlay button

WhenIn an immersive interface with a vivid colored background (audio player, mobile game) — a 44×44 px button in the corner shows the hamburger; it opens a full-screen settings panel where the cross is the only close affordance.
WhyAgainst a high-contrast background, thick white bars and the rotating cross are very legible — the animation itself communicates 'tap here to close' with no extra text or icon.
Settings3 px bars, white #fff, 300 ms ease duration, 44×44 px container (touch target), panel slides via translateX(100%)translateX(0).

How it works

Three <span> elements are absolute-positioned inside a 30×24 px relative container. By default: bar 1 at top:0, bar 2 centered via translateY(-50%), bar 3 at bottom:0. The entire animation is produced by transition: .3s on CSS properties — no JavaScript calculation involved.

Adding the .active class to the container triggers three simultaneous transitions: bar 1 rises to top:50%; transform: translateY(-50%) rotate(45deg), bar 2 disappears (opacity:0) while sliding left (translateX(-20px)), and bar 3 moves up to bottom:50%; transform: translateY(50%) rotate(-45deg). The two remaining bars cross exactly at the center to form an X.

The included JavaScript handles the site's mobile navigation (opening .mobile-menu, Escape key close, active-link highlighting) and theme switching — the hamburger's visual logic is purely CSS. In any integration, a single classList.toggle('active') is enough to drive the animation.

Accessibility

  • prefers-reduced-motion absent: the 300 ms transition runs regardless. To comply with WCAG 2.3.3, add @media (prefers-reduced-motion: reduce) { .hamburger span { transition: none; } }.
  • The container is a <div> with cursor:pointer — without role="button" or tabindex="0", it is invisible to keyboard users and screen readers. In production, use a native <button> element.
  • aria-expanded is absent: the open/closed state of the menu is not communicated to assistive technology. Add it to the trigger element and update it in JavaScript.
  • Bar contrast: white #fff on #0a0a0f background → ratio > 15:1, WCAG AA and AAA compliant.
  • The Escape key closes the mobile menu via the provided JS (targets .mobile-menu) — adapt this if your menu uses a different element.

Browser compatibility

Requires CSS Transitions (level 3) — supported in all modern browsers since 2012. Zero external dependencies.

Chrome 80+✓ Full
Firefox 75+✓ Full
Safari 13+✓ Full
Edge 80+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

Without CSS Transitions (IE 9-), bars snap instantly to the X position — the closed state remains legible, without animation.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<button class="hamburger" type="button" aria-expanded="false" aria-label="Menu">
  <span></span>
  <span></span>
  <span></span>
</button>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
width / height on .hamburger 30 px / 24 px Container size. Keep a 5:4 ratio so bars stay evenly spaced.
height on .hamburger span 3 px Bar thickness. 2 px = thin and elegant, 4–5 px = bold and assertive.
background on .hamburger span #fff Bar color. Replace with your brand color or a CSS custom property.
transition on .hamburger span .3s Duration and easing. .2s = snappy, .5s = cinematic. Example: .3s ease-in-out.
border-radius on .hamburger span 2 px Corner rounding on bar ends. 0 = sharp square, 100px = pill capsule.
translateX(-20px) in .active span:nth-child(2) -20 px Lateral slide distance of the middle bar before disappearing. Increase to -40 px for a more dramatic exit.

FAQ

Simply toggle the .active class on the .hamburger element: document.querySelector('.hamburger').classList.toggle('active'). No library needed.
Yes — edit the transition property on .hamburger span. Example: transition: .2s ease-in for a snappy close, or transition: .5s cubic-bezier(.68,-.55,.27,1.55) for a spring-back effect.
Yes. Copy the HTML and CSS, then manage a boolean state (isOpen) in your component: className={isOpen ? 'hamburger active' : 'hamburger'} (React) or :class="{'active': isOpen}" (Vue). No additional JavaScript adaptation needed.