16 CSS Mobile Navigation Patterns 09 / 16

Mega Menu Accordion

A light-mode mobile nav where a hamburger toggles a full-height drawer containing three accordion sections.

Pure CSS MIT licensed
Live Demo Open in tab

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

Open in playground

The code

<div class="mn-09">
  <input type="checkbox" id="mn-09-main">
  <input type="checkbox" id="mn-09-a1" class="mn-09__acc-check">
  <input type="checkbox" id="mn-09-a2" class="mn-09__acc-check">
  <input type="checkbox" id="mn-09-a3" class="mn-09__acc-check">

  <div class="mn-09__topbar">
    <div class="mn-09__logo">Green<span>Co</span></div>
    <label for="mn-09-main" class="mn-09__nav-toggle">
      <div class="mn-09__nav-toggle-bars">
        <span></span><span></span><span></span>
      </div>
      Menu
    </label>
  </div>

  <nav class="mn-09__nav-drawer">
    <div class="mn-09__acc-item">
      <label for="mn-09-a1" class="mn-09__acc-label">
        <div class="mn-09__acc-label-left">
          <div class="mn-09__acc-icon" style="background:rgba(5,150,105,0.1)">🌿</div>
          Products
        </div>
        <div class="mn-09__acc-chevron">▼</div>
      </label>
      <div class="mn-09__acc-body">
        <div class="mn-09__sub-links">
          <a href="#">Organic Skincare <span class="mn-09__sub-badge">New</span></a>
          <a href="#">Supplements</a>
          <a href="#">Home & Garden</a>
          <a href="#">Food & Beverages</a>
        </div>
      </div>
    </div>

    <div class="mn-09__acc-item">
      <label for="mn-09-a2" class="mn-09__acc-label">
        <div class="mn-09__acc-label-left">
          <div class="mn-09__acc-icon" style="background:rgba(8,145,178,0.1)">📚</div>
          Resources
        </div>
        <div class="mn-09__acc-chevron">▼</div>
      </label>
      <div class="mn-09__acc-body">
        <div class="mn-09__sub-links">
          <a href="#">Blog & Articles</a>
          <a href="#">Sustainability Guide</a>
          <a href="#">Community</a>
        </div>
        <div class="mn-09__acc-promo">
          <span style="font-size:24px">🌱</span>
          <p>Join <strong>12,000+</strong> readers — free newsletter every week.</p>
        </div>
      </div>
    </div>

    <div class="mn-09__acc-item">
      <label for="mn-09-a3" class="mn-09__acc-label">
        <div class="mn-09__acc-label-left">
          <div class="mn-09__acc-icon" style="background:rgba(124,58,237,0.1)">🏢</div>
          Company
        </div>
        <div class="mn-09__acc-chevron">▼</div>
      </label>
      <div class="mn-09__acc-body">
        <div class="mn-09__sub-links">
          <a href="#">About Us</a>
          <a href="#">Careers <span class="mn-09__sub-badge">Hiring</span></a>
          <a href="#">Press</a>
          <a href="#">Contact</a>
        </div>
      </div>
    </div>

    <div class="mn-09__nav-footer">
      <a href="#">Sign In</a>
      <a href="#">Get Started →</a>
    </div>
  </nav>

  <div class="mn-09__page">
    <h2>Sustainable Living</h2>
    <p>Eco-friendly products for a greener lifestyle.</p>
    <div class="mn-09__feature-grid">
      <div class="mn-09__feature">
        <div class="mn-09__feature-icon">♻️</div>
        <h4>100% Recycled</h4>
        <p>All packaging uses post-consumer materials.</p>
      </div>
      <div class="mn-09__feature">
        <div class="mn-09__feature-icon">🌍</div>
        <h4>Carbon Neutral</h4>
        <p>Certified carbon-neutral shipping worldwide.</p>
      </div>
      <div class="mn-09__feature">
        <div class="mn-09__feature-icon">🌿</div>
        <h4>Organic</h4>
        <p>USDA certified organic ingredients only.</p>
      </div>
      <div class="mn-09__feature">
        <div class="mn-09__feature-icon">🐰</div>
        <h4>Cruelty-Free</h4>
        <p>Never tested on animals. Leaping Bunny certified.</p>
      </div>
    </div>
  </div>
</div>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
body { display: flex; align-items: center; justify-content: center; min-height: 100vh; background: #0f0f13; font-family: 'Segoe UI', sans-serif; }

.mn-09 {
  --bg: #ffffff;
  --surface: #f9fafb;
  --border: #e5e7eb;
  --accent: #059669;
  --accent2: #0891b2;
  --accent3: #7c3aed;
  --text: #111827;
  --muted: #6b7280;
  width: 375px;
  height: 667px;
  position: relative;
  overflow: hidden;
  background: var(--bg);
  border-radius: 32px;
  box-shadow: 0 30px 80px rgba(0,0,0,0.5);
  display: flex;
  flex-direction: column;
}

.mn-09 input[type="checkbox"], .mn-09 input[type="radio"] { display: none; }

/* Top bar */
.mn-09__topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  z-index: 10;
  flex-shrink: 0;
}
.mn-09__logo {
  font-size: 18px;
  font-weight: 800;
  color: var(--text);
}
.mn-09__logo span { color: var(--accent); }
.mn-09__nav-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: 20px;
  transition: background 0.2s;
}
.mn-09__nav-toggle:hover { background: var(--surface); }
.mn-09__nav-toggle-bars {
  width: 16px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.mn-09__nav-toggle-bars span {
  display: block;
  height: 2px;
  background: var(--text);
  border-radius: 1px;
  transition: all 0.3s;
}
.mn-09__nav-toggle-bars span:nth-child(2) { width: 12px; }
#mn-09-main:checked ~ .mn-09__topbar .mn-09__nav-toggle .mn-09__nav-toggle-bars span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
#mn-09-main:checked ~ .mn-09__topbar .mn-09__nav-toggle .mn-09__nav-toggle-bars span:nth-child(2) { opacity: 0; }
#mn-09-main:checked ~ .mn-09__topbar .mn-09__nav-toggle .mn-09__nav-toggle-bars span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); width: 16px; }

/* Full nav drawer */
.mn-09__nav-drawer {
  position: absolute;
  top: 57px;
  left: 0; right: 0; bottom: 0;
  background: var(--bg);
  z-index: 9;
  transform: translateY(-100%);
  transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  overflow-y: auto;
}
#mn-09-main:checked ~ .mn-09__nav-drawer { transform: translateY(0); }

/* Accordion items */
.mn-09__acc-item { border-bottom: 1px solid var(--border); }
.mn-09__acc-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  gap: 8px;
}
.mn-09__acc-label-left {
  display: flex; align-items: center; gap: 12px;
}
.mn-09__acc-icon {
  width: 32px; height: 32px;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px;
}
.mn-09__acc-chevron {
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px;
  transition: transform 0.3s;
  color: var(--muted);
}
.mn-09__acc-body {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  background: var(--surface);
}
.mn-09__acc-check:checked ~ .mn-09__acc-item .mn-09__acc-body { max-height: 300px; }
.mn-09__acc-check:checked ~ .mn-09__acc-item .mn-09__acc-chevron { transform: rotate(180deg); }

.mn-09__sub-links { padding: 8px 0 16px 60px; }
.mn-09__sub-links a {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 20px 10px 0;
  color: var(--muted);
  text-decoration: none;
  font-size: 14px;
  transition: color 0.15s;
  border-bottom: 1px solid rgba(0,0,0,0.04);
}
.mn-09__sub-links a:last-child { border-bottom: none; }
.mn-09__sub-links a:hover { color: var(--text); }
.mn-09__sub-badge {
  margin-left: auto;
  font-size: 10px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 10px;
  background: rgba(5,150,105,0.12);
  color: var(--accent);
}

/* Promo strip in accordion */
.mn-09__acc-promo {
  margin: 0 16px 16px;
  padding: 14px;
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(5,150,105,0.08), rgba(8,145,178,0.08));
  border: 1px solid rgba(5,150,105,0.2);
  display: flex; align-items: center; gap: 12px;
}
.mn-09__acc-promo p { font-size: 13px; color: var(--text); line-height: 1.4; }
.mn-09__acc-promo strong { font-weight: 700; color: var(--accent); }

/* Nav footer */
.mn-09__nav-footer {
  padding: 20px;
  display: flex; gap: 10px;
}
.mn-09__nav-footer a {
  flex: 1;
  text-align: center;
  padding: 12px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}
.mn-09__nav-footer a:first-child { background: var(--surface); color: var(--text); border: 1px solid var(--border); }
.mn-09__nav-footer a:last-child { background: var(--accent); color: #fff; }

/* Page content */
.mn-09__page { flex: 1; padding: 20px; overflow-y: auto; }
.mn-09__page h2 { font-size: 22px; font-weight: 700; color: var(--text); margin-bottom: 4px; }
.mn-09__page p { color: var(--muted); font-size: 13px; margin-bottom: 20px; }
.mn-09__feature-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mn-09__feature {
  background: var(--surface);
  border-radius: 14px;
  padding: 16px;
  border: 1px solid var(--border);
}
.mn-09__feature-icon { font-size: 24px; margin-bottom: 8px; }
.mn-09__feature h4 { font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.mn-09__feature p { font-size: 11px; color: var(--muted); line-height: 1.4; margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .mn-09__nav-drawer, .mn-09__acc-body, .mn-09__acc-chevron, .mn-09__nav-toggle-bars span { transition: none; }
}

How this works

The main nav drawer is toggled by a master checkbox. Its transform: translateY(-100%) default slides it above the page; :checked transitions it to translateY(0). Each accordion section has its own independent checkbox — its .mn-09__acc-body starts at max-height: 0; overflow: hidden and transitions to max-height: 300px when its checkbox is checked.

The chevron icon rotates 180° via a sibling selector on the checked accordion checkbox. This is applied to .mn-09__acc-check:checked ~ .mn-09__acc-item .mn-09__acc-chevron. The hamburger bars morph into an x using the same translate-and-rotate technique as demo 01, styled as a pill button with a text label.

Customize

  • Add a fourth accordion by inserting another <input type="checkbox">, .mn-09__acc-item, and extending the sibling CSS rule for the new input ID.
  • Increase accordion max-height from 300px to 500px on sections with many sub-links — the transition still animates even though content is shorter than the max.
  • Change from translateY(-100%) drawer to a slide-from-right drawer by using translateX(100%) and positioning the drawer right: 0; top: 57px; width: 280px.
  • Style the promo strip differently per section by assigning unique gradient colours to each .mn-09__acc-promo — use a CSS custom property per section for easy overrides.
  • Remove accordion behaviour and show all sections expanded by default by removing all accordion checkboxes and setting .mn-09__acc-body { max-height: 500px } unconditionally.

Watch out for

  • max-height transitions have a known quirk: the transition duration feels uneven when content is much shorter than max-height — the visible motion only occupies a fraction of the total duration.
  • The master drawer checkbox and three accordion checkboxes must all be direct preceding siblings of their target elements; wrapping any in a <div> severs the CSS sibling chain.
  • On very short viewports (below 600px tall), the full-height drawer may clip the footer nav buttons — add overflow-y: auto to .mn-09__nav-drawer to allow scrolling.

Browser support

ChromeSafariFirefoxEdge
60+ 12+ 55+ 60+

max-height transition is fully supported in all modern browsers. No vendor prefixes required.

Search CodeFronts

Loading…