15 CSS Navigation Menu Designs06 / 15

CSS + JSMIT licensed

CSS Sticky Navigation Bar with Scroll Shrink

A sticky navigation bar that smoothly shrinks its height and adds a drop shadow as the user scrolls down, with a scroll-progress indicator bar at the top. The shrink effect is driven by a CSS class toggled via a tiny IntersectionObserver-based scroll listener.

Published

Live Demo
Try it

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

The code

<div class="nav-06">
  <div class="nav-06__progress" id="nav-06-progress"></div>
  <nav class="nav-06__bar" id="nav-06-bar">
    <div class="nav-06__logo">
      <span class="nav-06__logo-leaf">
        <svg viewBox="0 0 24 24"><path d="M12 22s-8-4.5-8-11.8A8 8 0 0112 2a8 8 0 018 8.2c0 7.3-8 11.8-8 11.8z"/></svg>
      </span>
      Verdant
    </div>
    <ul class="nav-06__links">
      <li><a href="#" class="nav-06__active">Home</a></li>
      <li><a href="#">Features</a></li>
      <li><a href="#">Pricing</a></li>
      <li><a href="#">Blog</a></li>
    </ul>
    <div class="nav-06__actions">
      <a href="#" class="nav-06__btn nav-06__btn--ghost">Login</a>
      <a href="#" class="nav-06__btn nav-06__btn--fill">Try free</a>
    </div>
  </nav>
  <div class="nav-06__hero">
    <h1>Sticky nav that<br><span>shrinks on scroll</span></h1>
    <p>Scroll down to see the navbar compress from 72px to 52px. JavaScript reads <code>scrollY</code> and toggles a class. All visual transitions are pure CSS.</p>
    <div class="nav-06__scroll-hint">
      <svg viewBox="0 0 24 24"><path d="M12 5v14M5 12l7 7 7-7"/></svg>
      Scroll down to trigger
    </div>
  </div>
  <div class="nav-06__content">
    <div class="nav-06__card">
      <h3>How it works</h3>
      <p>A tiny scroll event listener adds <code>.nav-06--shrunk</code> once <code>scrollY > 60</code>. The navbar's <code>height</code>, logo scale, and button size all transition via CSS. The scroll progress bar width is updated in the same handler.</p>
    </div>
    <div class="nav-06__card">
      <h3>Performance</h3>
      <p>Only <code>height</code>, <code>transform</code>, and <code>box-shadow</code> animate — height is handled via CSS transition on a sticky element, transform stays on the compositor.</p>
    </div>
    <div class="nav-06__card">
      <h3>Accessibility</h3>
      <p>The navbar remains fully keyboard-navigable throughout. The shrink behaviour is a visual enhancement only and doesn't affect focus order or ARIA roles.</p>
    </div>
  </div>
</div>
.nav-06,
.nav-06 *,
.nav-06 *::before,
.nav-06 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.nav-06 ::selection {
  background: #059669;
  color: #fff;
}

.nav-06 {
  --bg: #f0fdf4;
  --surface: #fff;
  --text: #052e16;
  --muted: #6b7280;
  --accent: #059669;
  --accent2: #34d399;
  --border: #d1fae5;
  font-family: 'Inter',system-ui,sans-serif;
  background: var(--bg);
  min-height: 200vh;
}

.nav-06__bar {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255,255,255,.9);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  padding: 0 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 72px;
  transition: height .3s ease,box-shadow .3s ease,border-color .3s;
}

.nav-06__bar.nav-06--shrunk {
  height: 52px;
  box-shadow: 0 4px 20px rgba(5,150,105,.1);
  border-color: rgba(5,150,105,.2);
}

.nav-06__logo {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 8px;
  transition: transform .3s ease;
}

.nav-06__bar.nav-06--shrunk .nav-06__logo {
  transform: scale(.9);
}

.nav-06__logo-leaf {
  width: 28px;
  height: 28px;
  background: var(--accent);
  border-radius: 50% 0 50% 50%;
  display: grid;
  place-items: center;
  transition: width .3s,height .3s;
}

.nav-06__bar.nav-06--shrunk .nav-06__logo-leaf {
  width: 22px;
  height: 22px;
}

.nav-06__logo-leaf svg {
  width: 14px;
  height: 14px;
  stroke: #fff;
  fill: none;
  stroke-width: 2;
}

.nav-06__links {
  display: flex;
  align-items: center;
  gap: 4px;
  list-style: none;
}

.nav-06__links a {
  padding: 7px 13px;
  color: var(--muted);
  text-decoration: none;
  font-size: .875rem;
  font-weight: 500;
  border-radius: 6px;
  transition: color .18s,background .18s;
}

.nav-06__links a:hover {
  color: var(--text);
  background: var(--border);
}

.nav-06__links a.nav-06__active {
  color: var(--accent);
  background: #ecfdf5;
}

.nav-06__actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.nav-06__btn {
  padding: 7px 16px;
  border-radius: 6px;
  font-size: .875rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: all .18s;
  display: inline-flex;
  align-items: center;
}

.nav-06__btn--ghost {
  color: var(--accent);
  background: transparent;
  border: 1.5px solid var(--border);
}

.nav-06__btn--ghost:hover {
  border-color: var(--accent2);
}

.nav-06__btn--fill {
  color: #fff;
  background: var(--accent);
  border: 1.5px solid var(--accent);
}

.nav-06__btn--fill:hover {
  opacity: .88;
}
/* shrink cta */

.nav-06__bar.nav-06--shrunk .nav-06__btn {
  padding: 5px 13px;
  font-size: .8125rem;
}
/* scroll indicator bar */

.nav-06__progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  z-index: 101;
  background: linear-gradient(90deg,var(--accent),var(--accent2));
  width: 0%;
  transition: width .1s linear;
}
/* sections */

.nav-06__hero {
  padding: 100px 48px;
  max-width: 800px;
  margin: 0 auto;
}

.nav-06__hero h1 {
  font-size: clamp(2.5rem,5vw,4rem);
  font-weight: 700;
  color: var(--text);
  letter-spacing: -.04em;
  line-height: 1.1;
  margin-bottom: 20px;
}

.nav-06__hero h1 span {
  color: var(--accent);
}

.nav-06__hero p {
  font-size: 1.0625rem;
  color: var(--muted);
  max-width: 520px;
  line-height: 1.7;
  margin-bottom: 32px;
}

.nav-06__scroll-hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--accent);
  font-size: .875rem;
  font-weight: 600;
  animation: nav-06-bounce 1.5s ease-in-out infinite;
}

.nav-06__scroll-hint svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
}

@keyframes nav-06-bounce {
  0%,
    100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(5px);
  }
}

.nav-06__content {
  padding: 60px 48px;
  max-width: 800px;
  margin: 0 auto;
}

.nav-06__card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 28px;
  margin-bottom: 24px;
}

.nav-06__card h3 {
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 8px;
}

.nav-06__card p {
  color: var(--muted);
  line-height: 1.65;
  font-size: .9375rem;
}

@media (max-width: 640px) {
  .nav-06__links,
    .nav-06__btn--ghost {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav-06__bar,
    .nav-06__logo,
    .nav-06__logo-leaf,
    .nav-06__btn,
    .nav-06__scroll-hint {
    transition: none;
    animation: none;
  }
}
(function(){
  var bar=document.getElementById('nav-06-bar');
  var prog=document.getElementById('nav-06-progress');
  function onScroll(){
    var y=window.scrollY;
    bar.classList.toggle('nav-06--shrunk',y>60);
    var doc=document.documentElement;
    var pct=y/(doc.scrollHeight-doc.clientHeight)*100;
    prog.style.width=Math.min(pct,100)+'%';
  }
  window.addEventListener('scroll',onScroll,{passive:true});
}());
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Navigation Menu Design from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Sticky Navigation Bar with Scroll Shrink
Source: https://codefronts.com/navigation/css-navigation-menu-designs/css-sticky-navigation-bar-with-scroll-shrink/

A sticky navigation bar that smoothly shrinks its height and adds a drop shadow as the user scrolls down, with a scroll-progress indicator bar at the top. The shrink effect is driven by a CSS class toggled via a tiny IntersectionObserver-based scroll listener.
## HTML
```html
<div class="nav-06">
  <div class="nav-06__progress" id="nav-06-progress"></div>
  <nav class="nav-06__bar" id="nav-06-bar">
    <div class="nav-06__logo">
      <span class="nav-06__logo-leaf">
        <svg viewBox="0 0 24 24"><path d="M12 22s-8-4.5-8-11.8A8 8 0 0112 2a8 8 0 018 8.2c0 7.3-8 11.8-8 11.8z"/></svg>
      </span>
      Verdant
    </div>
    <ul class="nav-06__links">
      <li><a href="#" class="nav-06__active">Home</a></li>
      <li><a href="#">Features</a></li>
      <li><a href="#">Pricing</a></li>
      <li><a href="#">Blog</a></li>
    </ul>
    <div class="nav-06__actions">
      <a href="#" class="nav-06__btn nav-06__btn--ghost">Login</a>
      <a href="#" class="nav-06__btn nav-06__btn--fill">Try free</a>
    </div>
  </nav>
  <div class="nav-06__hero">
    <h1>Sticky nav that<br><span>shrinks on scroll</span></h1>
    <p>Scroll down to see the navbar compress from 72px to 52px. JavaScript reads <code>scrollY</code> and toggles a class. All visual transitions are pure CSS.</p>
    <div class="nav-06__scroll-hint">
      <svg viewBox="0 0 24 24"><path d="M12 5v14M5 12l7 7 7-7"/></svg>
      Scroll down to trigger
    </div>
  </div>
  <div class="nav-06__content">
    <div class="nav-06__card">
      <h3>How it works</h3>
      <p>A tiny scroll event listener adds <code>.nav-06--shrunk</code> once <code>scrollY > 60</code>. The navbar's <code>height</code>, logo scale, and button size all transition via CSS. The scroll progress bar width is updated in the same handler.</p>
    </div>
    <div class="nav-06__card">
      <h3>Performance</h3>
      <p>Only <code>height</code>, <code>transform</code>, and <code>box-shadow</code> animate — height is handled via CSS transition on a sticky element, transform stays on the compositor.</p>
    </div>
    <div class="nav-06__card">
      <h3>Accessibility</h3>
      <p>The navbar remains fully keyboard-navigable throughout. The shrink behaviour is a visual enhancement only and doesn't affect focus order or ARIA roles.</p>
    </div>
  </div>
</div>

```
## CSS
```css
.nav-06,
.nav-06 *,
.nav-06 *::before,
.nav-06 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.nav-06 ::selection {
  background: #059669;
  color: #fff;
}

.nav-06 {
  --bg: #f0fdf4;
  --surface: #fff;
  --text: #052e16;
  --muted: #6b7280;
  --accent: #059669;
  --accent2: #34d399;
  --border: #d1fae5;
  font-family: 'Inter',system-ui,sans-serif;
  background: var(--bg);
  min-height: 200vh;
}

.nav-06__bar {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255,255,255,.9);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  padding: 0 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 72px;
  transition: height .3s ease,box-shadow .3s ease,border-color .3s;
}

.nav-06__bar.nav-06--shrunk {
  height: 52px;
  box-shadow: 0 4px 20px rgba(5,150,105,.1);
  border-color: rgba(5,150,105,.2);
}

.nav-06__logo {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: 8px;
  transition: transform .3s ease;
}

.nav-06__bar.nav-06--shrunk .nav-06__logo {
  transform: scale(.9);
}

.nav-06__logo-leaf {
  width: 28px;
  height: 28px;
  background: var(--accent);
  border-radius: 50% 0 50% 50%;
  display: grid;
  place-items: center;
  transition: width .3s,height .3s;
}

.nav-06__bar.nav-06--shrunk .nav-06__logo-leaf {
  width: 22px;
  height: 22px;
}

.nav-06__logo-leaf svg {
  width: 14px;
  height: 14px;
  stroke: #fff;
  fill: none;
  stroke-width: 2;
}

.nav-06__links {
  display: flex;
  align-items: center;
  gap: 4px;
  list-style: none;
}

.nav-06__links a {
  padding: 7px 13px;
  color: var(--muted);
  text-decoration: none;
  font-size: .875rem;
  font-weight: 500;
  border-radius: 6px;
  transition: color .18s,background .18s;
}

.nav-06__links a:hover {
  color: var(--text);
  background: var(--border);
}

.nav-06__links a.nav-06__active {
  color: var(--accent);
  background: #ecfdf5;
}

.nav-06__actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.nav-06__btn {
  padding: 7px 16px;
  border-radius: 6px;
  font-size: .875rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: all .18s;
  display: inline-flex;
  align-items: center;
}

.nav-06__btn--ghost {
  color: var(--accent);
  background: transparent;
  border: 1.5px solid var(--border);
}

.nav-06__btn--ghost:hover {
  border-color: var(--accent2);
}

.nav-06__btn--fill {
  color: #fff;
  background: var(--accent);
  border: 1.5px solid var(--accent);
}

.nav-06__btn--fill:hover {
  opacity: .88;
}
/* shrink cta */

.nav-06__bar.nav-06--shrunk .nav-06__btn {
  padding: 5px 13px;
  font-size: .8125rem;
}
/* scroll indicator bar */

.nav-06__progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  z-index: 101;
  background: linear-gradient(90deg,var(--accent),var(--accent2));
  width: 0%;
  transition: width .1s linear;
}
/* sections */

.nav-06__hero {
  padding: 100px 48px;
  max-width: 800px;
  margin: 0 auto;
}

.nav-06__hero h1 {
  font-size: clamp(2.5rem,5vw,4rem);
  font-weight: 700;
  color: var(--text);
  letter-spacing: -.04em;
  line-height: 1.1;
  margin-bottom: 20px;
}

.nav-06__hero h1 span {
  color: var(--accent);
}

.nav-06__hero p {
  font-size: 1.0625rem;
  color: var(--muted);
  max-width: 520px;
  line-height: 1.7;
  margin-bottom: 32px;
}

.nav-06__scroll-hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--accent);
  font-size: .875rem;
  font-weight: 600;
  animation: nav-06-bounce 1.5s ease-in-out infinite;
}

.nav-06__scroll-hint svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
}

@keyframes nav-06-bounce {
  0%,
    100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(5px);
  }
}

.nav-06__content {
  padding: 60px 48px;
  max-width: 800px;
  margin: 0 auto;
}

.nav-06__card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 28px;
  margin-bottom: 24px;
}

.nav-06__card h3 {
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 8px;
}

.nav-06__card p {
  color: var(--muted);
  line-height: 1.65;
  font-size: .9375rem;
}

@media (max-width: 640px) {
  .nav-06__links,
    .nav-06__btn--ghost {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav-06__bar,
    .nav-06__logo,
    .nav-06__logo-leaf,
    .nav-06__btn,
    .nav-06__scroll-hint {
    transition: none;
    animation: none;
  }
}
```

## JavaScript
```js
(function(){
  var bar=document.getElementById('nav-06-bar');
  var prog=document.getElementById('nav-06-progress');
  function onScroll(){
    var y=window.scrollY;
    bar.classList.toggle('nav-06--shrunk',y>60);
    var doc=document.documentElement;
    var pct=y/(doc.scrollHeight-doc.clientHeight)*100;
    prog.style.width=Math.min(pct,100)+'%';
  }
  window.addEventListener('scroll',onScroll,{passive:true});
}());
```

How this works

A sentinel `
` is placed at the top of the page. An `IntersectionObserver` watches it — when it leaves the viewport (user scrolled past), the JS adds `.nav-06--shrunk` to the nav. CSS transitions `padding`, `height`, and `box-shadow` smoothly. A scroll progress bar uses `scrollY / (scrollHeight - clientHeight)` to drive a `width` percentage.

Make it yours

  • Adjust `.nav-06--shrunk` padding/height values to control the shrink amount. Change `--progress-color` to customize the progress bar. Swap `IntersectionObserver` threshold to control the scroll trigger point.

Gotchas — read before shipping

  • The nav must be `position: sticky; top: 0` with a `z-index` above page content. Ensure the sentinel element is not inside a `transform` or `will-change` parent, which creates a new stacking context that breaks `sticky` positioning.

Browser support

ChromeSafariFirefoxEdge
76+9+103+76+

Floor set by backdrop-filter as this demo is written. The core technique itself goes back further — Chrome .

Techniques used in this demo

Search CodeFronts

Loading…