Skip to content
Larwell Technologies
Home / Code Playground / Navigation
Navigation

Pure CSS Hamburger Menu Morph to X

A sleek pure CSS hamburger menu icon that smoothly morphs into an X close button using only CSS transforms and transitions. No JavaScript required.

By Ishrafil Khan Updated June 2026 Bokaro Steel City, India
CSSAnimationHamburgerMenu Icon
Live Preview
HTML + CSS + JS
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pure CSS Hamburger Morph to X</title>
    <style>
        /* ============ CSS Custom Properties ============ */
        :root {
            --bar-width: 28px;
            --bar-height: 3px;
            --bar-gap: 7px;
            --bar-radius: 3px;
            --color-bar: #ffffff;
            --color-bg: #1a1a2e;
            --color-accent: #e94560;
            --color-overlay: rgba(0, 0, 0, 0.5);
            --sidebar-width: 280px;
            --transition-speed: 0.35s;
            --transition-ease: cubic-bezier(0.65, 0.05, 0.36, 1);
            --font-main: 'Segoe UI', system-ui, -apple-system, sans-serif;
        }

        *,
        *::before,
        *::after {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: var(--font-main);
            background: #f0f0f5;
            min-height: 100vh;
            overflow-x: hidden;
        }

        /* ============ Header ============ */
        .header {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            z-index: 100;
            height: 60px;
            background: var(--color-bg);
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0 24px;
            box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
        }

        .header__logo {
            color: #fff;
            font-size: 1.3rem;
            font-weight: 700;
            letter-spacing: 0.5px;
            user-select: none;
        }

        .header__logo span {
            color: var(--color-accent);
        }

        /* ============ Hidden Checkbox ============ */
        .menu-toggle {
            display: none;
            /* truly hidden */;
        }

        /* ============ Hamburger Label ============ */
        .hamburger-label {
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            width: 44px;
            height: 44px;
            cursor: pointer;
            z-index: 200;
            position: relative;
            -webkit-tap-highlight-color: transparent;
            user-select: none;
        }

        /* The three bars */
        .hamburger-label .bar {
            display: block;
            width: var(--bar-width);
            height: var(--bar-height);
            background: var(--color-bar);
            border-radius: var(--bar-radius);
            transition:
                transform var(--transition-speed) var(--transition-ease),
                opacity var(--transition-speed) var(--transition-ease),
                background var(--transition-speed) var(--transition-ease);
            position: absolute;
            left: 50%;
            transform: translateX(-50%);
            will-change: transform, opacity;
        }

        .hamburger-label .bar--top {
            top: 50%;
            transform: translateX(-50%) translateY(calc(-1 * var(--bar-gap) - var(--bar-height)));
        }

        .hamburger-label .bar--middle {
            top: 50%;
            transform: translateX(-50%) translateY(-50%);
        }

        .hamburger-label .bar--bottom {
            top: 50%;
            transform: translateX(-50%) translateY(var(--bar-gap));
        }

        /* ============ MORPH TO X on :checked ============ */
        .menu-toggle:checked+.hamburger-label .bar--top {
            transform: translateX(-50%) translateY(0) rotate(45deg);
            background: var(--color-accent);
        }

        .menu-toggle:checked+.hamburger-label .bar--middle {
            opacity: 0;
            transform: translateX(-50%) translateY(-50%) scaleX(0);
        }

        .menu-toggle:checked+.hamburger-label .bar--bottom {
            transform: translateX(-50%) translateY(0) rotate(-45deg);
            background: var(--color-accent);
        }

        /* ============ Sidebar Overlay ============ */
        .overlay {
            position: fixed;
            inset: 0;
            background: var(--color-overlay);
            z-index: 90;
            opacity: 0;
            pointer-events: none;
            transition: opacity var(--transition-speed) var(--transition-ease);
        }

        .menu-toggle:checked~.overlay {
            opacity: 1;
            pointer-events: auto;
        }

        /* ============ Slide-Out Sidebar ============ */
        .sidebar {
            position: fixed;
            top: 0;
            left: 0;
            width: var(--sidebar-width);
            height: 100vh;
            background: #fff;
            z-index: 95;
            padding: 80px 28px 28px;
            transform: translateX(-100%);
            transition: transform var(--transition-speed) var(--transition-ease);
            box-shadow: 4px 0 24px rgba(0, 0, 0, 0.12);
            display: flex;
            flex-direction: column;
            gap: 8px;
        }

        .menu-toggle:checked~.sidebar {
            transform: translateX(0);
        }

        /* Sidebar nav links */
        .sidebar__nav {
            list-style: none;
            padding: 0;
            margin: 0;
            display: flex;
            flex-direction: column;
            gap: 4px;
        }

        .sidebar__nav a {
            display: block;
            padding: 14px 18px;
            text-decoration: none;
            color: #333;
            font-weight: 500;
            font-size: 1.05rem;
            border-radius: 10px;
            transition: background 0.2s, color 0.2s;
            letter-spacing: 0.3px;
        }

        .sidebar__nav a:hover {
            background: #f5f5fa;
            color: var(--color-accent);
        }

        .sidebar__nav a.active {
            background: var(--color-accent);
            color: #fff;
            font-weight: 600;
        }

        .sidebar__divider {
            height: 1px;
            background: #e8e8ee;
            margin: 8px 0;
        }

        /* ============ Page Content ============ */
        .page-content {
            padding: 100px 32px 40px;
            max-width: 720px;
            margin: 0 auto;
        }

        .page-content h1 {
            font-size: 2rem;
            color: #1a1a2e;
            margin-bottom: 12px;
            letter-spacing: -0.3px;
        }

        .page-content p {
            color: #555;
            line-height: 1.7;
            font-size: 1.05rem;
            margin-bottom: 16px;
        }

        .page-content .badge {
            display: inline-block;
            background: #e8e8f0;
            color: #555;
            padding: 6px 14px;
            border-radius: 20px;
            font-size: 0.85rem;
            font-weight: 600;
            letter-spacing: 0.3px;
            margin-right: 6px;
            margin-bottom: 6px;
        }

        /* ============ Responsive ============ */
        @media (max-width: 480px) {
            .sidebar {
                width: 100vw;
            }
            .page-content {
                padding: 90px 20px 30px;
            }
            .page-content h1 {
                font-size: 1.6rem;
            }
        }
    </style>
</head>
<body>

    <!-- Hidden checkbox controls the menu state -->
    <input type="checkbox" id="menu-toggle" class="menu-toggle">

    <!-- The hamburger / X icon label -->
    <header class="header">
        <div class="header__logo">Morph<span>Menu</span></div>
        <label for="menu-toggle" class="hamburger-label" aria-label="Toggle navigation menu">
            <span class="bar bar--top"></span>
            <span class="bar bar--middle"></span>
            <span class="bar bar--bottom"></span>
        </label>
    </header>

    <!-- Overlay (clicking it closes the menu) -->
    <label for="menu-toggle" class="overlay" aria-hidden="true"></label>

    <!-- Slide-out sidebar navigation -->
    <aside class="sidebar">
        <ul class="sidebar__nav">
            <li><a href="#" class="active">🏠 Home</a></li>
            <li><a href="#">📄 About</a></li>
            <li><a href="#">🛠 Services</a></li>
            <li><a href="#">📁 Portfolio</a></li>
            <li class="sidebar__divider"></li>
            <li><a href="#">✉️ Contact</a></li>
            <li><a href="#">⚙️ Settings</a></li>
        </ul>
    </aside>

    <!-- Demo page content -->
    <main class="page-content">
        <h1>Pure CSS Hamburger → X Morph</h1>
        <p>
            Click the hamburger icon in the top-right corner of the header.
            Watch as the three bars smoothly morph into an <strong>X</strong> close button &mdash;
            all driven by pure CSS with zero JavaScript.
        </p>
        <div>
            <span class="badge">Pure CSS</span>
            <span class="badge">No JavaScript</span>
            <span class="badge">Checkbox Hack</span>
            <span class="badge">Smooth Transitions</span>
        </div>
        <p style="margin-top: 20px;">
            The sidebar slides in from the left, and a semi-transparent overlay appears behind it.
            Click the overlay, the X button, or press the <strong>Escape</strong> key
            (via the label&rsquo;s built-in checkbox toggle) to close the menu.
            The entire interaction is handled by CSS <code>:checked</code> pseudo-class
            combined with sibling combinators.
        </p>
    </main>

</body>
</html>

This is a pure CSS hamburger menu icon that elegantly morphs into an X when toggled. The animation uses CSS transforms and transitions triggered by a hidden checkbox input — a classic "checkbox hack" technique. Each of the three bars animates independently: the top bar rotates down, the bottom bar rotates up, and the middle bar fades away, creating a satisfying morphing effect.

How it works

The core mechanism relies on the CSS sibling combinator (~ or +) combined with a hidden checkbox input. A <label> element wraps three <span> bars. When the user clicks the label, it toggles the checkbox. CSS rules targeting input:checked ~ label then apply transforms to each span. The top bar gets transform: rotate(45deg) translateY(...), the middle bar gets opacity: 0, and the bottom bar gets transform: rotate(-45deg) translateY(...). Smooth transition properties on all bars ensure the morph feels fluid and natural.

How to use it

  • Copy the HTML structure: an invisible checkbox, a label with three spans, and any menu content you want to toggle.
  • The CSS uses :checked to drive the animation. No JavaScript is needed.
  • To toggle additional elements like a sidebar, use the general sibling combinator (~) to target them from the checkbox’s checked state.
  • Adjust the $bar-width, $bar-height, and $bar-gap CSS custom properties at the top of the styles to resize the icon.
  • Customize the colors by modifying the --color-bar and --color-bg variables.
Free to use under the MIT license. Built by Ishrafil Khanneed a custom build?