20 CSS Hamburger Menus 06 / 20

Minimalist / Floating Hamburger Button

A fixed corner FAB that stays accessible through a long multi-section scroll.

CSS + JS MIT licensed
Live Demo Open in tab
Open in playground

The code

<div class="chm-06">
  <div class="chm-06__scene">
    <div class="chm-06__scroller">
      <section class="chm-06__s1">
        <div class="chm-06__idx">Floating · Always reachable</div>
        <h2>Scroll<br>as far as you <i>like.</i></h2>
        <p>The button stays pinned to the corner — no header bar, no clutter. Tap it any time to bloom the menu.</p>
        <div class="chm-06__bigmark">01</div>
      </section>
      <section class="chm-06__s2">
        <div class="chm-06__idx">Section Two</div>
        <h2>Still <i>here.</i></h2>
        <p>Hundreds of pixels down the page and the control hasn't moved. Minimalism that never abandons the user.</p>
        <div class="chm-06__bigmark">02</div>
      </section>
      <section class="chm-06__s3">
        <div class="chm-06__idx">Section Three</div>
        <h2>Tap to <i>bloom.</i></h2>
        <p>A radial micro-menu unfurls from the button with spring easing — playful, fast, out of the way.</p>
        <div class="chm-06__bigmark">03</div>
      </section>
    </div>

    <div class="chm-06__scrim"></div>
    <div class="chm-06__bloom">
      <a href="#">Home</a>
      <a href="#">Work</a>
      <a href="#">Info</a>
      <a href="#">Say hi</a>
    </div>
    <button class="chm-06__fab" aria-label="Toggle floating menu">
      <span class="chm-06__b"><i></i><i></i><i></i></span>
    </button>
    <div class="chm-06__scrollhint">↓ Scroll · button stays</div>
  </div>
</div>
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@300;400;500;600&display=swap');

.chm-06, .chm-06 *, .chm-06 *::before, .chm-06 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
.chm-06{
  --paper:#ece8e1;--ink:#1a1a1a;--blush:#e8826b;--sage:#8a9b6e;
  min-height:460px;display:grid;place-items:stretch;
  font-family:'Geist',sans-serif;background:var(--paper);color:var(--ink);
  position:relative;
}
.chm-06__scene{position:relative;width:100%;min-height:460px;height:100%;overflow:hidden}
.chm-06__scroller{position:relative;width:100%;height:460px;overflow-y:auto;scroll-behavior:smooth}
.chm-06__scroller section{min-height:460px;display:flex;flex-direction:column;justify-content:center;padding:0 clamp(20px,6vw,80px);position:relative}
.chm-06__idx{font-size:11px;letter-spacing:.4em;text-transform:uppercase;color:var(--blush);font-weight:500;margin-bottom:16px}
.chm-06__scroller section h2{font-family:'Instrument Serif',serif;font-weight:400;font-size:clamp(2rem,7vw,4.4rem);line-height:.98;letter-spacing:-.01em}
.chm-06__scroller section h2 i{color:var(--blush)}
.chm-06__scroller section p{margin-top:16px;max-width:380px;font-size:.95rem;line-height:1.6;color:#555}
.chm-06__s1{background:radial-gradient(120% 100% at 70% 0%,rgba(232,130,107,.14),transparent 55%),var(--paper)}
.chm-06__s2{background:var(--ink);color:var(--paper)}
.chm-06__s2 h2 i{color:var(--sage)}.chm-06__s2 p{color:rgba(236,232,225,.6)}.chm-06__s2 .chm-06__idx{color:var(--sage)}
.chm-06__s3{background:linear-gradient(160deg,#ddd6cb,var(--paper))}
.chm-06__bigmark{position:absolute;right:-2%;bottom:-6%;font-family:'Instrument Serif',serif;font-style:italic;font-size:20vw;line-height:.7;opacity:.05;pointer-events:none;user-select:none}
.chm-06__fab{position:absolute;bottom:24px;right:24px;z-index:80;width:60px;height:60px;border-radius:50%;cursor:pointer;
  background:var(--ink);color:var(--paper);display:grid;place-items:center;
  box-shadow:0 16px 40px rgba(26,26,26,.28);
  transition:transform .5s cubic-bezier(.34,1.56,.64,1),background .4s;border:none}
.chm-06__fab:hover{transform:scale(1.08) rotate(-4deg)}
.chm-06__b{width:22px;height:13px;position:relative}
.chm-06__b i{position:absolute;left:0;height:2.2px;width:100%;background:var(--paper);border-radius:3px;transition:transform .5s cubic-bezier(.7,0,.2,1),opacity .3s,width .4s}
.chm-06__b i:nth-child(1){top:0}.chm-06__b i:nth-child(2){top:5.5px;width:65%}.chm-06__b i:nth-child(3){top:11px}
.chm-06.is-open .chm-06__fab{background:var(--blush)}
.chm-06.is-open .chm-06__b i:nth-child(1){transform:translateY(5.5px) rotate(45deg)}
.chm-06.is-open .chm-06__b i:nth-child(2){opacity:0;width:0}
.chm-06.is-open .chm-06__b i:nth-child(3){transform:translateY(-5.5px) rotate(-45deg)}
.chm-06__bloom{position:absolute;bottom:24px;right:24px;z-index:75;width:60px;height:60px;pointer-events:none}
.chm-06__bloom a{position:absolute;bottom:0;right:0;width:50px;height:50px;border-radius:50%;display:grid;place-items:center;text-decoration:none;
  background:rgba(236,232,225,.95);backdrop-filter:blur(10px);border:1px solid rgba(26,26,26,.08);
  color:var(--ink);font-size:10px;font-weight:600;letter-spacing:.04em;text-align:center;
  box-shadow:0 8px 22px rgba(26,26,26,.16);
  transform:scale(.2);opacity:0;pointer-events:none;
  transition:transform .55s cubic-bezier(.34,1.56,.64,1),opacity .4s}
.chm-06.is-open .chm-06__bloom{pointer-events:auto}
.chm-06.is-open .chm-06__bloom a{opacity:1;pointer-events:auto;transform:scale(1)}
.chm-06.is-open .chm-06__bloom a:nth-child(1){bottom:78px;right:5px;transition-delay:.05s}
.chm-06.is-open .chm-06__bloom a:nth-child(2){bottom:66px;right:72px;transition-delay:.11s}
.chm-06.is-open .chm-06__bloom a:nth-child(3){bottom:5px;right:78px;transition-delay:.17s}
.chm-06.is-open .chm-06__bloom a:nth-child(4){bottom:120px;right:50px;transition-delay:.23s}
.chm-06__bloom a:hover{background:var(--ink);color:var(--paper)}
.chm-06__scrim{position:absolute;inset:0;z-index:70;background:rgba(26,26,26,.12);backdrop-filter:blur(3px);opacity:0;pointer-events:none;transition:.4s}
.chm-06.is-open .chm-06__scrim{opacity:1;pointer-events:auto}
.chm-06__scrollhint{position:absolute;top:24px;left:24px;z-index:5;font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:rgba(26,26,26,.4);font-weight:500}

@media (prefers-reduced-motion: reduce){
  .chm-06__fab,.chm-06__b i,.chm-06__bloom a,.chm-06__scrim,.chm-06__scroller{transition:none !important;scroll-behavior:auto !important}
}
(() => {
  const root = document.querySelector('.chm-06');
  if (!root) return;
  const btn = root.querySelector('.chm-06__fab');
  const scrim = root.querySelector('.chm-06__scrim');
  btn.addEventListener('click', () => root.classList.toggle('is-open'));
  scrim.addEventListener('click', () => root.classList.remove('is-open'));
})();

Search CodeFronts

Loading…