Open demo

CSS code

HTML
<header class="hm">
  <a class="logo" href="#">proto<em>kit</em></a>
  <nav class="panel" id="hm-panel" aria-label="Main">
    <ul class="links">
      <li class="item">
        <button class="top sub-btn" type="button" aria-expanded="false" aria-controls="hm-products">Products <svg aria-hidden="true" width="10" height="10" viewBox="0 0 10 10"><path d="M2 3.5 5 6.5 8 3.5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></button>
        <div class="mega" id="hm-products">
          <div class="col"><p class="ttl" id="hm-build">Build</p>
            <ul aria-labelledby="hm-build">
              <li><a href="#"><b>Components</b><span>400+ ready UI blocks</span></a></li>
              <li><a href="#"><b>Templates</b><span>Full pages, wired up</span></a></li>
              <li><a href="#"><b>Icons</b><span>Consistent 2px set</span></a></li>
            </ul>
          </div>
          <div class="col"><p class="ttl" id="hm-ship">Ship</p>
            <ul aria-labelledby="hm-ship">
              <li><a href="#"><b>Hosting</b><span>Deploy on git push</span></a></li>
              <li><a href="#"><b>Forms</b><span>Backendless submissions</span></a></li>
              <li><a href="#"><b>Analytics</b><span>Private by default</span></a></li>
            </ul>
          </div>
          <div class="col"><p class="ttl" id="hm-learn">Learn</p>
            <ul aria-labelledby="hm-learn">
              <li><a href="#"><b>Guides</b><span>From zero to shipped</span></a></li>
              <li><a href="#"><b>Changelog</b><span>What's new weekly</span></a></li>
              <li><a href="#"><b>Community</b><span>12k builders</span></a></li>
            </ul>
          </div>
          <a class="promo" href="#"><b>New: Dark mode kit</b><span>Every component, retuned for night. Free this month.</span></a>
        </div>
      </li>
      <li class="item"><a class="top" href="#">Pricing</a></li>
      <li class="item"><a class="top" href="#" aria-current="page">Customers</a></li>
      <li class="item"><a class="top" href="#">Docs</a></li>
    </ul>
  </nav>
  <a class="cta" href="#">Get started</a>
  <button class="toggle" type="button" aria-expanded="false" aria-controls="hm-panel" aria-label="Menu"><i></i><i></i><i></i></button>
</header>
CSS
/* Header with a full-width mega menu: three link columns and a promo card.
   Opens on hover (pointer devices, 992px and up) and on click or Enter; below 992px it stacks inside the menu. */
.hm{--hm-ink:#151a24;--hm-muted:#454f63;--hm-accent:#7c3aed;--hm-line:#e9edf3;
  position:relative;z-index:30;display:flex;align-items:center;gap:30px;min-height:68px;padding:0 36px;background:#fff;
  border-bottom:1px solid var(--hm-line);color:var(--hm-ink);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
.hm,.hm *{box-sizing:border-box}
.hm ul{list-style:none;margin:0;padding:0}
.hm a{text-decoration:none}
.hm a:focus-visible,.hm button:focus-visible{outline:2px solid var(--hm-accent);outline-offset:2px}
.hm .logo{font-weight:900;font-size:1.05rem;letter-spacing:-.02em;color:var(--hm-ink);border-radius:6px}
.hm .logo em{font-style:normal;color:var(--hm-accent)}
.hm .panel{align-self:stretch;margin-right:auto}
.hm .links{display:flex;height:100%}
.hm .top{height:100%;display:flex;align-items:center;gap:6px;padding:0 16px;font:inherit;font-size:.9rem;font-weight:600;color:var(--hm-muted);
  background:none;border:0;border-bottom:2px solid transparent;cursor:pointer;transition:color .15s,border-color .15s}
.hm .top:focus-visible{outline-offset:-4px;border-radius:8px}
.hm .top:hover,.hm .top[aria-expanded="true"],.hm .top[aria-current="page"]{color:var(--hm-accent);border-bottom-color:var(--hm-accent)}
.hm .top svg{transition:transform .15s}
.hm .top[aria-expanded="true"] svg{transform:rotate(180deg)}
.hm .mega{position:absolute;left:0;right:0;top:100%;display:grid;grid-template-columns:repeat(3,1fr) 260px;gap:8px;padding:26px 36px;
  background:#fff;border-bottom:1px solid var(--hm-line);box-shadow:0 30px 50px -30px rgba(20,25,45,.3);
  opacity:0;visibility:hidden;transform:translateY(8px);transition:opacity .18s,transform .18s,visibility .18s}
.hm .mega[data-open]{opacity:1;visibility:visible;transform:none}
@media (min-width:992px) and (hover:hover){.hm .item:hover .mega{opacity:1;visibility:visible;transform:none}}
.hm .ttl{font-size:.72rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#6b7385;margin:0 0 10px}
.hm .col a{display:block;padding:9px 10px;margin-left:-10px;border-radius:9px;transition:background .12s}
.hm .col a:hover{background:#f5f2fd}
.hm .col b{display:block;font-size:.88rem;color:var(--hm-ink)}
.hm .col span{font-size:.76rem;color:#5f6878}
.hm .promo{display:flex;flex-direction:column;justify-content:flex-end;min-height:170px;padding:20px;border-radius:14px;color:#fff;background:linear-gradient(150deg,#7c3aed,#4f46e5)}
.hm .promo b{font-size:.95rem;margin-bottom:4px}
.hm .promo span{font-size:.78rem;opacity:.92}
.hm .cta{font-size:.86rem;font-weight:700;color:#fff;background:var(--hm-ink);padding:10px 18px;border-radius:10px;white-space:nowrap}
.hm .toggle{display:none;width:44px;height:44px;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  background:#fff;border:1px solid #d9dee8;border-radius:10px;cursor:pointer}
.hm .toggle i{display:block;width:20px;height:2px;border-radius:2px;background:var(--hm-ink);transition:transform .2s,opacity .2s}
.hm .toggle[aria-expanded="true"] i:nth-child(1){transform:translateY(7px) rotate(45deg)}
.hm .toggle[aria-expanded="true"] i:nth-child(2){opacity:0}
.hm .toggle[aria-expanded="true"] i:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
@media (max-width:991.98px){
  .hm{flex-wrap:wrap;gap:0 12px;padding:12px 16px}
  .hm .toggle{display:flex}
  .hm .cta{margin-left:auto}
  .hm .panel{display:none;align-self:auto;order:9;flex-basis:100%;margin:0;padding:10px 0 4px}
  .hm .panel[data-open]{display:block}
  .hm .links{flex-direction:column;gap:2px;height:auto}
  .hm .top{width:100%;height:auto;padding:11px 14px;border:0;border-radius:9px}
  .hm .top:hover,.hm .top[aria-expanded="true"],.hm .top[aria-current="page"]{background:#f5f2fd}
  .hm .mega{position:static;display:none;grid-template-columns:1fr;gap:14px;padding:10px 4px 14px 24px;border:0;box-shadow:none;opacity:1;visibility:visible;transform:none}
  .hm .mega[data-open]{display:grid}
  .hm .promo{min-height:0}
}
@media (prefers-reduced-motion:reduce){.hm *{transition:none!important}}
JavaScript
/* Menu button (below 992px) and the Products mega menu are disclosure buttons: each toggles aria-expanded
   and a data-open attribute on the element it controls. Esc closes the open one and returns focus. */
(() => {
  const hd = document.querySelector('.hm'); if (!hd) return;
  const toggle = hd.querySelector('.toggle'), subs = [...hd.querySelectorAll('.sub-btn')];
  const set = (btn, open) => { btn.setAttribute('aria-expanded', open); document.getElementById(btn.getAttribute('aria-controls')).toggleAttribute('data-open', open); };
  const isOpen = btn => btn.getAttribute('aria-expanded') === 'true';
  toggle.addEventListener('click', () => set(toggle, !isOpen(toggle)));
  subs.forEach(btn => {
    btn.addEventListener('click', () => { const open = !isOpen(btn); subs.forEach(b => set(b, false)); set(btn, open); });
    btn.parentElement.addEventListener('focusout', e => { if (!btn.parentElement.contains(e.relatedTarget)) set(btn, false); });
  });
  document.addEventListener('click', e => subs.forEach(b => { if (!b.parentElement.contains(e.target)) set(b, false); }));
  document.addEventListener('keydown', e => {
    if (e.key !== 'Escape') return;
    const sub = subs.find(isOpen);
    if (sub) { set(sub, false); sub.focus(); } else if (isOpen(toggle)) { set(toggle, false); toggle.focus(); }
  });
})();

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS, Bootstrap 5.3.8 JS bundle

HTML
<header class="hm">
  <nav class="navbar navbar-expand-lg" aria-label="Main">
    <div class="container-fluid">
      <a class="navbar-brand" href="#">proto<em>kit</em></a>
      <div class="d-flex align-items-center gap-2 ms-auto order-lg-last">
        <a class="btn cta" href="#">Get started</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#hm-panel" aria-controls="hm-panel" aria-expanded="false" aria-label="Menu"><i></i><i></i><i></i></button>
      </div>
      <div class="collapse navbar-collapse" id="hm-panel">
        <ul class="navbar-nav">
          <li class="nav-item dropdown position-static">
            <button class="nav-link dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Products <svg aria-hidden="true" width="10" height="10" viewBox="0 0 10 10"><path d="M2 3.5 5 6.5 8 3.5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></button>
            <div class="dropdown-menu mega">
              <div class="col"><p class="ttl" id="hm-build">Build</p>
                <ul class="list-unstyled m-0" aria-labelledby="hm-build">
                  <li><a href="#"><b>Components</b><span>400+ ready UI blocks</span></a></li>
                  <li><a href="#"><b>Templates</b><span>Full pages, wired up</span></a></li>
                  <li><a href="#"><b>Icons</b><span>Consistent 2px set</span></a></li>
                </ul>
              </div>
              <div class="col"><p class="ttl" id="hm-ship">Ship</p>
                <ul class="list-unstyled m-0" aria-labelledby="hm-ship">
                  <li><a href="#"><b>Hosting</b><span>Deploy on git push</span></a></li>
                  <li><a href="#"><b>Forms</b><span>Backendless submissions</span></a></li>
                  <li><a href="#"><b>Analytics</b><span>Private by default</span></a></li>
                </ul>
              </div>
              <div class="col"><p class="ttl" id="hm-learn">Learn</p>
                <ul class="list-unstyled m-0" aria-labelledby="hm-learn">
                  <li><a href="#"><b>Guides</b><span>From zero to shipped</span></a></li>
                  <li><a href="#"><b>Changelog</b><span>What's new weekly</span></a></li>
                  <li><a href="#"><b>Community</b><span>12k builders</span></a></li>
                </ul>
              </div>
              <a class="promo" href="#"><b>New: Dark mode kit</b><span>Every component, retuned for night. Free this month.</span></a>
            </div>
          </li>
          <li class="nav-item"><a class="nav-link" href="#">Pricing</a></li>
          <li class="nav-item"><a class="nav-link active" href="#" aria-current="page">Customers</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Docs</a></li>
        </ul>
      </div>
    </div>
  </nav>
</header>
CSS
/* Bootstrap .navbar-expand-lg with a full-width .dropdown-menu: the .dropdown is .position-static,
   so the menu is placed against the .navbar (position: relative) and stretched edge to edge. */
.hm{--hm-ink:#151a24;--hm-muted:#454f63;--hm-accent:#7c3aed;--hm-line:#e9edf3}
.hm .navbar{--bs-navbar-padding-y:0;--bs-navbar-padding-x:36px;--bs-navbar-color:var(--hm-muted);--bs-navbar-hover-color:var(--hm-accent);
  --bs-navbar-active-color:var(--hm-accent);--bs-navbar-brand-color:var(--hm-ink);--bs-navbar-brand-hover-color:var(--hm-ink);
  --bs-navbar-brand-padding-y:0;--bs-navbar-brand-margin-end:0;--bs-navbar-nav-link-padding-x:16px;
  z-index:30;min-height:68px;background:#fff;border-bottom:1px solid var(--hm-line)}
.hm .container-fluid{padding:0;gap:30px}
.hm .navbar-brand{font-weight:900;font-size:1.05rem;letter-spacing:-.02em;border-radius:6px}
.hm .navbar-brand em{font-style:normal;color:var(--hm-accent)}
.hm .navbar-nav{--bs-nav-link-font-weight:600;--bs-nav-link-font-size:.9rem}
.hm .nav-link{display:flex;align-items:center;gap:6px;border-bottom:2px solid transparent;transition:color .15s,border-color .15s}
.hm .nav-link:hover,.hm .nav-link.show,.hm .nav-link.active{border-bottom-color:var(--hm-accent)}
.hm .dropdown-toggle::after{display:none}
.hm .dropdown-toggle svg{transition:transform .15s}
.hm .dropdown-toggle.show svg{transform:rotate(180deg)}
.hm .mega{--bs-dropdown-border-radius:0;--bs-dropdown-border-width:0;--bs-dropdown-spacer:0;--bs-dropdown-padding-x:36px;--bs-dropdown-padding-y:26px;
  right:0;grid-template-columns:repeat(3,1fr) 260px;gap:8px;border-bottom:1px solid var(--hm-line);box-shadow:0 30px 50px -30px rgba(20,25,45,.3)}
.hm .mega.show{display:grid}
.hm .ttl{font-size:.72rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#6b7385;margin:0 0 10px}
.hm .col a{display:block;padding:9px 10px;margin-left:-10px;border-radius:9px;text-decoration:none;transition:background .12s}
.hm .col a:hover{background:#f5f2fd}
.hm .col b{display:block;font-size:.88rem;color:var(--hm-ink)}
.hm .col span{font-size:.76rem;color:#5f6878}
.hm .promo{display:flex;flex-direction:column;justify-content:flex-end;min-height:170px;padding:20px;border-radius:14px;color:#fff;text-decoration:none;background:linear-gradient(150deg,#7c3aed,#4f46e5)}
.hm .promo b{font-size:.95rem;margin-bottom:4px}
.hm .promo span{font-size:.78rem;opacity:.92}
.hm .cta{--bs-btn-font-size:.86rem;--bs-btn-font-weight:700;--bs-btn-padding-x:18px;--bs-btn-padding-y:10px;--bs-btn-border-radius:10px;--bs-btn-border-width:0;
  --bs-btn-color:#fff;--bs-btn-bg:var(--hm-ink);--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#262d3b;--bs-btn-active-color:#fff;--bs-btn-active-bg:#262d3b;white-space:nowrap}
.hm a:focus-visible,.hm button:focus-visible{outline:2px solid var(--hm-accent);outline-offset:2px;box-shadow:none}
.hm .nav-link:focus-visible{outline-offset:-4px;border-radius:8px}
.hm .navbar-toggler{width:44px;height:44px;padding:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;border:1px solid #d9dee8;border-radius:10px}
.hm .navbar-toggler i{display:block;width:20px;height:2px;border-radius:2px;background:var(--hm-ink);transition:transform .2s,opacity .2s}
.hm .navbar-toggler[aria-expanded="true"] i:nth-child(1){transform:translateY(7px) rotate(45deg)}
.hm .navbar-toggler[aria-expanded="true"] i:nth-child(2){opacity:0}
.hm .navbar-toggler[aria-expanded="true"] i:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
@media (min-width:992px){
  .hm .navbar-toggler{display:none}
  .hm .container-fluid,.hm .navbar-collapse,.hm .navbar-nav{align-self:stretch}
  .hm .nav-link{height:100%}
}
@media (max-width:991.98px){
  .hm .navbar{--bs-navbar-padding-x:16px;padding-top:12px;padding-bottom:12px}
  .hm .container-fluid{gap:0}
  .hm .navbar-nav{gap:2px;padding:10px 0 4px}
  .hm .navbar-nav .nav-link{width:100%;padding:11px 14px;border:0;border-radius:9px}
  .hm .nav-link:hover,.hm .nav-link.show,.hm .nav-link.active{background:#f5f2fd}
  .hm .mega{grid-template-columns:1fr;gap:14px;padding:10px 4px 14px 24px;border:0;box-shadow:none}
  .hm .promo{min-height:0}
}
@media (prefers-reduced-motion:reduce){.hm *{transition:none!important}}
JavaScript
/* Bootstrap closes an open dropdown on Esc; this also closes the collapsed menu on Esc (below 992px)
   and returns focus to the menu button. Capture phase, so an open dropdown gets the first Esc. */
document.addEventListener('keydown', e => {
  if (e.key !== 'Escape') return;
  const panel = document.querySelector('.hm .navbar-collapse.show');
  if (!panel || panel.querySelector('.dropdown-menu.show')) return;
  bootstrap.Collapse.getOrCreateInstance(panel).hide();
  document.querySelector(`[data-bs-target="#${panel.id}"]`).focus();
}, true);

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<header class="hm relative z-30 flex min-h-[68px] items-center gap-[30px] border-b border-hm-line bg-white px-9 max-lg:flex-wrap max-lg:gap-x-3 max-lg:gap-y-0 max-lg:px-4 max-lg:py-3">
  <a class="rounded-md text-[1.05rem] font-black tracking-[-.02em] text-hm-ink focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent" href="#">proto<em class="text-hm-accent not-italic">kit</em></a>
  <nav class="mr-auto hidden self-stretch data-open:block lg:block max-lg:order-9 max-lg:m-0 max-lg:basis-full max-lg:self-auto max-lg:pt-2.5 max-lg:pb-1" id="hm-panel" aria-label="Main">
    <ul class="flex h-full max-lg:h-auto max-lg:flex-col max-lg:gap-0.5">
      <li class="group/item">
        <button class="sub-btn group flex h-full cursor-pointer items-center gap-1.5 border-b-2 border-transparent px-4 text-[.9rem] font-semibold text-hm-muted transition-colors duration-150 hover:border-hm-accent hover:text-hm-accent focus-visible:rounded-lg focus-visible:outline-2 focus-visible:-outline-offset-4 focus-visible:outline-hm-accent aria-expanded:border-hm-accent aria-expanded:text-hm-accent motion-reduce:transition-none max-lg:h-auto max-lg:w-full max-lg:rounded-[9px] max-lg:border-0 max-lg:px-3.5 max-lg:py-[11px] max-lg:hover:bg-hm-tint max-lg:aria-expanded:bg-hm-tint" type="button" aria-expanded="false" aria-controls="hm-products">Products <svg class="transition-transform duration-150 group-aria-expanded:rotate-180 motion-reduce:transition-none" aria-hidden="true" width="10" height="10" viewBox="0 0 10 10"><path d="M2 3.5 5 6.5 8 3.5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></button>
        <div class="invisible absolute inset-x-0 top-full grid translate-y-2 grid-cols-[repeat(3,1fr)_260px] gap-2 border-b border-hm-line bg-white px-9 py-[26px] opacity-0 shadow-[0_30px_50px_-30px_rgba(20,25,45,.3)] transition-[opacity,transform,visibility] duration-[180ms] data-open:visible data-open:translate-y-0 data-open:opacity-100 motion-reduce:transition-none lg:group-hover/item:visible lg:group-hover/item:translate-y-0 lg:group-hover/item:opacity-100 max-lg:visible max-lg:static max-lg:hidden max-lg:translate-y-0 max-lg:grid-cols-1 max-lg:gap-3.5 max-lg:border-0 max-lg:pt-2.5 max-lg:pr-1 max-lg:pb-3.5 max-lg:pl-6 max-lg:opacity-100 max-lg:shadow-none max-lg:data-open:grid" id="hm-products">
          <div><p class="mb-2.5 text-[.72rem] font-extrabold tracking-[.08em] text-[#6b7385] uppercase" id="hm-build">Build</p>
            <ul aria-labelledby="hm-build">
              <li><a class="-ml-2.5 block rounded-[9px] px-2.5 py-[9px] transition-colors duration-100 hover:bg-hm-tint focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent motion-reduce:transition-none" href="#"><b class="block text-[.88rem] text-hm-ink">Components</b><span class="text-[.76rem] text-[#5f6878]">400+ ready UI blocks</span></a></li>
              <li><a class="-ml-2.5 block rounded-[9px] px-2.5 py-[9px] transition-colors duration-100 hover:bg-hm-tint focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent motion-reduce:transition-none" href="#"><b class="block text-[.88rem] text-hm-ink">Templates</b><span class="text-[.76rem] text-[#5f6878]">Full pages, wired up</span></a></li>
              <li><a class="-ml-2.5 block rounded-[9px] px-2.5 py-[9px] transition-colors duration-100 hover:bg-hm-tint focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent motion-reduce:transition-none" href="#"><b class="block text-[.88rem] text-hm-ink">Icons</b><span class="text-[.76rem] text-[#5f6878]">Consistent 2px set</span></a></li>
            </ul>
          </div>
          <div><p class="mb-2.5 text-[.72rem] font-extrabold tracking-[.08em] text-[#6b7385] uppercase" id="hm-ship">Ship</p>
            <ul aria-labelledby="hm-ship">
              <li><a class="-ml-2.5 block rounded-[9px] px-2.5 py-[9px] transition-colors duration-100 hover:bg-hm-tint focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent motion-reduce:transition-none" href="#"><b class="block text-[.88rem] text-hm-ink">Hosting</b><span class="text-[.76rem] text-[#5f6878]">Deploy on git push</span></a></li>
              <li><a class="-ml-2.5 block rounded-[9px] px-2.5 py-[9px] transition-colors duration-100 hover:bg-hm-tint focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent motion-reduce:transition-none" href="#"><b class="block text-[.88rem] text-hm-ink">Forms</b><span class="text-[.76rem] text-[#5f6878]">Backendless submissions</span></a></li>
              <li><a class="-ml-2.5 block rounded-[9px] px-2.5 py-[9px] transition-colors duration-100 hover:bg-hm-tint focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent motion-reduce:transition-none" href="#"><b class="block text-[.88rem] text-hm-ink">Analytics</b><span class="text-[.76rem] text-[#5f6878]">Private by default</span></a></li>
            </ul>
          </div>
          <div><p class="mb-2.5 text-[.72rem] font-extrabold tracking-[.08em] text-[#6b7385] uppercase" id="hm-learn">Learn</p>
            <ul aria-labelledby="hm-learn">
              <li><a class="-ml-2.5 block rounded-[9px] px-2.5 py-[9px] transition-colors duration-100 hover:bg-hm-tint focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent motion-reduce:transition-none" href="#"><b class="block text-[.88rem] text-hm-ink">Guides</b><span class="text-[.76rem] text-[#5f6878]">From zero to shipped</span></a></li>
              <li><a class="-ml-2.5 block rounded-[9px] px-2.5 py-[9px] transition-colors duration-100 hover:bg-hm-tint focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent motion-reduce:transition-none" href="#"><b class="block text-[.88rem] text-hm-ink">Changelog</b><span class="text-[.76rem] text-[#5f6878]">What's new weekly</span></a></li>
              <li><a class="-ml-2.5 block rounded-[9px] px-2.5 py-[9px] transition-colors duration-100 hover:bg-hm-tint focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent motion-reduce:transition-none" href="#"><b class="block text-[.88rem] text-hm-ink">Community</b><span class="text-[.76rem] text-[#5f6878]">12k builders</span></a></li>
            </ul>
          </div>
          <a class="flex min-h-[170px] flex-col justify-end rounded-[14px] bg-linear-150/srgb from-[#7c3aed] to-[#4f46e5] p-5 text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent max-lg:min-h-0" href="#"><b class="mb-1 text-[.95rem]">New: Dark mode kit</b><span class="text-[.78rem] opacity-92">Every component, retuned for night. Free this month.</span></a>
        </div>
      </li>
      <li><a class="flex h-full items-center border-b-2 border-transparent px-4 text-[.9rem] font-semibold text-hm-muted transition-colors duration-150 hover:border-hm-accent hover:text-hm-accent focus-visible:rounded-lg focus-visible:outline-2 focus-visible:-outline-offset-4 focus-visible:outline-hm-accent motion-reduce:transition-none max-lg:h-auto max-lg:rounded-[9px] max-lg:border-0 max-lg:px-3.5 max-lg:py-[11px] max-lg:hover:bg-hm-tint" href="#">Pricing</a></li>
      <li><a class="flex h-full items-center border-b-2 border-hm-accent px-4 text-[.9rem] font-semibold text-hm-accent focus-visible:rounded-lg focus-visible:outline-2 focus-visible:-outline-offset-4 focus-visible:outline-hm-accent max-lg:h-auto max-lg:rounded-[9px] max-lg:border-0 max-lg:bg-hm-tint max-lg:px-3.5 max-lg:py-[11px]" href="#" aria-current="page">Customers</a></li>
      <li><a class="flex h-full items-center border-b-2 border-transparent px-4 text-[.9rem] font-semibold text-hm-muted transition-colors duration-150 hover:border-hm-accent hover:text-hm-accent focus-visible:rounded-lg focus-visible:outline-2 focus-visible:-outline-offset-4 focus-visible:outline-hm-accent motion-reduce:transition-none max-lg:h-auto max-lg:rounded-[9px] max-lg:border-0 max-lg:px-3.5 max-lg:py-[11px] max-lg:hover:bg-hm-tint" href="#">Docs</a></li>
    </ul>
  </nav>
  <a class="rounded-[10px] bg-hm-ink px-[18px] py-2.5 text-[.86rem] font-bold whitespace-nowrap text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent max-lg:ml-auto" href="#">Get started</a>
  <button class="toggle group flex size-11 cursor-pointer flex-col items-center justify-center gap-[5px] rounded-[10px] border border-[#d9dee8] bg-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-hm-accent lg:hidden" type="button" aria-expanded="false" aria-controls="hm-panel" aria-label="Menu">
    <i class="block h-0.5 w-5 rounded-sm bg-hm-ink transition-transform duration-200 group-aria-expanded:translate-y-[7px] group-aria-expanded:rotate-45 motion-reduce:transition-none"></i>
    <i class="block h-0.5 w-5 rounded-sm bg-hm-ink transition-opacity duration-200 group-aria-expanded:opacity-0 motion-reduce:transition-none"></i>
    <i class="block h-0.5 w-5 rounded-sm bg-hm-ink transition-transform duration-200 group-aria-expanded:-translate-y-[7px] group-aria-expanded:-rotate-45 motion-reduce:transition-none"></i>
  </button>
</header>
CSS
@theme {
  --breakpoint-lg: 62rem; /* 992px, the same collapse point as Bootstrap's navbar-expand-lg */
  --color-hm-ink: #151a24;
  --color-hm-muted: #454f63;
  --color-hm-accent: #7c3aed;
  --color-hm-line: #e9edf3;
  --color-hm-tint: #f5f2fd;
}
JavaScript
/* Menu button (below 992px) and the Products mega menu are disclosure buttons: each toggles aria-expanded
   and a data-open attribute on the element it controls. Esc closes the open one and returns focus. */
(() => {
  const hd = document.querySelector('.hm'); if (!hd) return;
  const toggle = hd.querySelector('.toggle'), subs = [...hd.querySelectorAll('.sub-btn')];
  const set = (btn, open) => { btn.setAttribute('aria-expanded', open); document.getElementById(btn.getAttribute('aria-controls')).toggleAttribute('data-open', open); };
  const isOpen = btn => btn.getAttribute('aria-expanded') === 'true';
  toggle.addEventListener('click', () => set(toggle, !isOpen(toggle)));
  subs.forEach(btn => {
    btn.addEventListener('click', () => { const open = !isOpen(btn); subs.forEach(b => set(b, false)); set(btn, open); });
    btn.parentElement.addEventListener('focusout', e => { if (!btn.parentElement.contains(e.relatedTarget)) set(btn, false); });
  });
  document.addEventListener('click', e => subs.forEach(b => { if (!b.parentElement.contains(e.target)) set(b, false); }));
  document.addEventListener('keydown', e => {
    if (e.key !== 'Escape') return;
    const sub = subs.find(isOpen);
    if (sub) { set(sub, false); sub.focus(); } else if (isOpen(toggle)) { set(toggle, false); toggle.focus(); }
  });
})();

About this set

A product header whose Products item opens a full-width mega menu: three labelled columns of links (Build, Ship and Learn), each link with a bold name and a short description, and a purple gradient promo card on the right. The other items, Pricing, Customers and Docs, are plain links with a purple underline on hover and on the current page, and a dark Get started button closes the row. The panel is positioned against the header, so it spans the full width whatever the width of the Products link. With a mouse it opens on hover; it is also a button that opens on click or Enter and closes on Esc, an outside click or when focus moves away. Below 992px the navigation folds behind a menu button, and the mega menu becomes a single stacked column inside that panel, promo card last. Use it for component libraries, SaaS suites and any site with more than a dozen destinations to group. The Bootstrap version uses a .position-static .dropdown so its .dropdown-menu stretches across the .navbar.

What’s included

  • Full-width panel with three labelled link columns and a promo card
  • Hover to preview, click or Enter to open, Esc to close
  • Column titles label their lists with aria-labelledby
  • Stacks into one column inside the phone menu
  • Purple underline marks hover and the current page

Accessibility

Links are in a nav labelled Main, with aria-current="page" on Customers. Products and the menu button are buttons with aria-expanded and aria-controls; Esc closes the open one and puts focus back on it, and tabbing out of the mega menu closes it. Each column list is labelled by its title, grey text was darkened to reach 4.5:1, and transitions stop under prefers-reduced-motion.

Customise it

Change --hm-accent, --hm-ink, --hm-muted and --hm-line on .hm, and the grid-template-columns of .mega for a different column count. In Bootstrap the same variables sit beside the --bs-navbar-* and --bs-dropdown-* ones; in Tailwind edit the --color-hm-* theme colours and the grid-cols utility on the panel.