AI CSS Animations

Glass Header on Scroll

A sticky site header that starts clear and frosts over once the page scrolls under it, blurring the hero as it passes. The demo loops the scroll; on a real site, a scroll timeline drives the fade.

Also known as: glassmorphism header css, sticky glass header css, frosted navbar on scroll.

Sign in

HTML

<div class="gls-glass-header-on-scroll">
  <div class="gls-glass-header-on-scroll-page" aria-hidden="true">
    <p class="gls-glass-header-on-scroll-kicker">New in 4.0</p>
    <p class="gls-glass-header-on-scroll-hero">Design that<br>stays clear.</p>
    <p class="gls-glass-header-on-scroll-lede">Glass that frosts only when the page moves under it.</p>
    <div class="gls-glass-header-on-scroll-grid">
      <span></span><span></span><span></span>
      <span></span><span></span><span></span>
      <span></span><span></span><span></span>
    </div>
  </div>
  <header class="gls-glass-header-on-scroll-bar">
    <a class="gls-glass-header-on-scroll-logo" href="#"><i></i>Lumen</a>
    <nav class="gls-glass-header-on-scroll-nav" aria-label="Main">
      <a href="#">Work</a>
      <a href="#">Pricing</a>
      <a href="#">Docs</a>
    </nav>
    <a class="gls-glass-header-on-scroll-cta" href="#">Sign in</a>
  </header>
</div>

CSS

.gls-glass-header-on-scroll {
  --c: var(--gls-color, #3b82f6);
  font-size: var(--gls-size, 16px);
  position: relative;
  display: block;
  width: 22em;
  height: 12em;
  border-radius: 1.25em;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 28%, #0b1020), #0b1020);
  color: #fff;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.3;
}
.gls-glass-header-on-scroll-page {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  padding: 3.6em 1.3em 1em;
  animation: gls-glass-header-on-scroll-scroll 9s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}
.gls-glass-header-on-scroll-page::before {
  content: "";
  position: absolute;
  z-index: -1;
  right: -2em;
  top: 1.2em;
  width: 12em;
  height: 9em;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--c), transparent);
  opacity: 0.85;
}
.gls-glass-header-on-scroll-kicker {
  display: inline-block;
  margin: 0 0 0.9em;
  padding: 0.35em 0.8em;
  border: 1px solid color-mix(in srgb, var(--c) 60%, transparent);
  border-radius: 99em;
  background: color-mix(in srgb, var(--c) 25%, transparent);
  font-size: 0.55em;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.gls-glass-header-on-scroll-hero {
  margin: 0;
  font-size: 1.95em;
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.035em;
  background: linear-gradient(100deg, #fff 45%, color-mix(in srgb, var(--c) 40%, #fff));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.gls-glass-header-on-scroll-lede {
  margin: 0.6em 0 1.1em;
  font-size: 0.66em;
  opacity: 0.7;
}
.gls-glass-header-on-scroll-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5em;
}
.gls-glass-header-on-scroll-grid span {
  height: 3em;
  border-radius: 0.7em;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.3);
}
.gls-glass-header-on-scroll-grid span:nth-child(4n + 1) { background: linear-gradient(135deg, color-mix(in srgb, var(--c) 40%, #fff), var(--c)); }
.gls-glass-header-on-scroll-grid span:nth-child(4n + 2) { background: linear-gradient(135deg, #fde68a, #f472b6); }
.gls-glass-header-on-scroll-grid span:nth-child(4n + 3) { background: linear-gradient(135deg, #5eead4, #6366f1); }
.gls-glass-header-on-scroll-grid span:nth-child(4n) { background: linear-gradient(135deg, #fdba74, #a855f7); }
.gls-glass-header-on-scroll-bar {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: 0.9em;
  height: 2.6em;
  padding: 0 0.8em 0 1.3em;
}
/* the frost: faded in as content scrolls underneath */
.gls-glass-header-on-scroll-bar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-bottom: 1px solid rgb(255 255 255 / 0.28);
  background: rgb(255 255 255 / 0.14);
  -webkit-backdrop-filter: blur(0.8em) saturate(1.6);
  backdrop-filter: blur(0.8em) saturate(1.6);
  box-shadow: 0 0.5em 1.2em -0.6em rgb(0 0 0 / 0.55);
  opacity: 0;
  animation: gls-glass-header-on-scroll-frost 9s ease infinite;
}
.gls-glass-header-on-scroll-logo {
  display: flex;
  align-items: center;
  gap: 0.4em;
  color: #fff;
  font-size: 0.8em;
  font-weight: 750;
  letter-spacing: -0.01em;
  text-decoration: none;
}
.gls-glass-header-on-scroll-logo i {
  width: 1.1em;
  height: 1.1em;
  border-radius: 0.35em;
  background: linear-gradient(135deg, color-mix(in srgb, var(--c) 40%, #fff), var(--c));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.5);
}
.gls-glass-header-on-scroll-nav {
  display: flex;
  gap: 0.15em;
  margin-left: auto;
}
.gls-glass-header-on-scroll-nav a {
  padding: 0.45em 0.7em;
  border-radius: 99em;
  color: rgb(255 255 255 / 0.8);
  font-size: 0.66em;
  font-weight: 600;
  text-decoration: none;
  transition: background-color 0.25s ease, color 0.25s ease;
}
.gls-glass-header-on-scroll-nav a:hover { background: rgb(255 255 255 / 0.16); color: #fff; }
.gls-glass-header-on-scroll-cta {
  padding: 0.5em 0.95em;
  border-radius: 99em;
  background: #fff;
  color: color-mix(in srgb, var(--c) 60%, #0f172a);
  font-size: 0.66em;
  font-weight: 700;
  text-decoration: none;
  transition: scale 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.gls-glass-header-on-scroll-cta:hover { scale: 1.06; }
.gls-glass-header-on-scroll-bar a:focus-visible { outline: 2px solid #fff; outline-offset: 0.15em; }
@keyframes gls-glass-header-on-scroll-scroll {
  0%, 10% { transform: translateY(0); }
  40%, 60% { transform: translateY(-7em); }
  90%, 100% { transform: translateY(0); }
}
@keyframes gls-glass-header-on-scroll-frost {
  0%, 14% { opacity: 0; }
  24%, 78% { opacity: 1; }
  88%, 100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .gls-glass-header-on-scroll, .gls-glass-header-on-scroll *, .gls-glass-header-on-scroll::before, .gls-glass-header-on-scroll::after, .gls-glass-header-on-scroll *::before, .gls-glass-header-on-scroll *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --gls-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --gls-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar glass effects