25 hand-coded CSS sticky navigation patterns for SaaS marketing headers, e-commerce storefronts, documentation shells, article readers, and mobile app views. Covers shrink-on-scroll, hide-on-scroll-down / reveal-on-scroll-up, transparent-to-solid over hero, sticky mega menu, cart-badge header, dual-stacked announcement bar, sidebar table-of-contents, and mobile bottom tab bar with env(safe-area-inset-bottom). 7 Pure CSS + 18 Light JS. Scoped under .sn-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.

7 pure CSS18 light JSPublished

Related15 CSS Navigation Menu Designs28 CSS Hamburger Menus16 CSS Mobile Navigation Patterns32 CSS Tab Designs

Pure CSS Sticky Navbar (No JavaScript, position:sticky) — preview
01 / 25Pure CSS

Pure CSS Sticky Navbar (No JavaScript, position:sticky)

The baseline sticky header every other pattern in this collection extends. Two declarations pin a marketing or blog header to the top of its scroll container, and the rest of the demo is the part tutorials skip: why the header stops sticking when a parent has overflow:hidden, and how to stop in-page anchor links from landing underneath the bar.

Published

Sticky Top Header with Flexbox Layout (Logo · Links · CTA) — preview
02 / 25Pure CSS

Sticky Top Header with Flexbox Layout (Logo · Links · CTA)

The three-zone product header — brand locked left, navigation held in the true optical centre, action button pinned right — that stays balanced when the link set grows or a locale doubles the label lengths. Built on auto margins rather than space-between, which is why the centre group does not drift every time the CTA text changes.

Published

Responsive Sticky Navbar with Hamburger Menu Toggle — preview
03 / 25Light JS

Responsive Sticky Navbar with Hamburger Menu Toggle

The mobile header that ships on most marketing sites, built the way an accessibility audit expects it: a real button that reports its state, a drawer that traps nothing but is properly hidden from assistive tech when closed, Escape and outside-click dismissal, and focus that returns to the toggle. The hamburger-to-close morph is pure CSS transforms.

Published

Sticky Header with Full-Bleed Bar and Container Max-Width Content — preview
04 / 25Pure CSS

Sticky Header with Full-Bleed Bar and Container Max-Width Content

The layout contract behind almost every corporate site: the sticky bar's background, border and shadow run edge to edge, while the logo and links sit on exactly the same left margin as the article below. Uses a named-line grid so the page and the header share one measurement, rather than repeating a magic 1200px in six stylesheets.

Published

Floating Glass Pill Sticky Navbar (Rounded, Backdrop Blur, Elevation) — preview
05 / 25Pure CSS

Floating Glass Pill Sticky Navbar (Rounded, Backdrop Blur, Elevation)

The detached pill header used across modern product and portfolio sites: lifted away from the viewport edge, rounded to a full radius, and frosted so the page reads through it as it scrolls past. The demo covers the two things that make or break the effect — a genuinely layered rim light instead of a flat border, and a solid fallback where backdrop blur is unavailable.

Published

Sticky Header Shrink on Scroll (80px → 50px, Compact State) — preview
06 / 25Light JS

Sticky Header Shrink on Scroll (80px → 50px, Compact State)

The tall-at-rest header that compacts into a slim bar once the reader is past the first screen — buying back vertical space on long pages without ever losing the navigation. Driven by a scroll-progress timeline in CSS, so the shrink interpolates smoothly with the scroll position instead of snapping at a threshold, with a small script covering engines that have not shipped the timeline yet.

Published

Sticky Nav with Directional Hide (Scroll Down) and Reveal (Scroll Up) — preview
07 / 25Light JS

Sticky Nav with Directional Hide (Scroll Down) and Reveal (Scroll Up)

Reading-first navigation: the header slides out of the way while the reader moves down the page and snaps back the instant they scroll up, so the nav is always one small gesture away without permanently costing 64px of screen. The demo focuses on the two details that separate a polished implementation from a twitchy one — a movement dead zone and a rest state at the very top.

Published

Transparent-to-Solid Sticky Header on Hero Scroll — preview
08 / 25Light JS

Transparent-to-Solid Sticky Header on Hero Scroll

The hero pattern used on almost every launch page: the header sits transparently over full-bleed imagery, then takes on a solid, legible background the moment it starts overlapping real content. Implemented with the scroll-state container query — CSS can now style a stuck element without a single scroll listener — plus a sentinel-based fallback for engines that have not shipped it.

Published

Sticky Header with Article Reading Progress Bar Underneath — preview
09 / 25Light JS

Sticky Header with Article Reading Progress Bar Underneath

The publisher's progress indicator: a 3px fill welded to the bottom edge of the sticky header that tracks how far through the article the reader is. Runs entirely on a scroll-progress timeline, so the fill is driven by the compositor rather than by a scroll handler recalculating document height on every frame.

Published

Sticky Header with SVG Logo Wordmark → Mark-Only Morph on Scroll — preview
10 / 25Light JS

Sticky Header with SVG Logo Wordmark → Mark-Only Morph on Scroll

The identity move used by large product sites: a full wordmark while the reader is at the top, cross-fading to the compact mark once the header pins, reclaiming horizontal space for navigation on narrow screens. Both lockups are inline SVG in one grid cell, so the swap costs no layout shift and no second network request.

Published

Sticky Navbar with Underline-Slide Active Link Indicator — preview
11 / 25Light JS

Sticky Navbar with Underline-Slide Active Link Indicator

The indicator that glides between links instead of fading in place — the detail that makes a header feel engineered rather than assembled. One shared underline element is translated and resized to whatever link is hovered, focused or current, so the motion always reads as a single object moving, not four separate underlines taking turns.

Published

Sticky Header with Theme-Aware Token Swap (Light/Dark) — preview
12 / 25Light JS

Sticky Header with Theme-Aware Token Swap (Light/Dark)

Theming a sticky header is harder than theming a page, because translucent chrome has to stay legible over whatever scrolls beneath it in both schemes. This demo wires the modern token cascade — system preference as the default, an explicit override on top — using the light-dark() function, so a single token definition serves both themes instead of two duplicated blocks.

Published

Minimalist Sticky Header with Single High-Emphasis CTA — preview
13 / 25Pure CSS

Minimalist Sticky Header with Single High-Emphasis CTA

A landing-page header stripped to what actually converts: a wordmark, three links and one unmistakable action. The engineering interest is in restraint — how a single accent colour, one weight step and a 4px shadow do the entire job of hierarchy, with nothing competing for the click.

Published

Split Sticky Navbar with Centered Brand Logo (Links Left + Right) — preview
14 / 25Pure CSS

Split Sticky Navbar with Centered Brand Logo (Links Left + Right)

The symmetrical header favoured by fashion, hospitality and editorial brands: navigation split into two wings with the wordmark holding the centre. The layout must keep the logo optically centred even when one wing has three links and the other has two — which is exactly what 1fr auto 1fr guarantees and flexbox does not.

Published

Neumorphic Sticky Navigation Bar (Soft-UI Inset/Outset Shadows) — preview
15 / 25Pure CSS

Neumorphic Sticky Navigation Bar (Soft-UI Inset/Outset Shadows)

Soft-UI applied to a sticky bar, with the physics done properly: every raised surface casts one light and one dark shadow from a single consistent light source, and active items invert to inset so they read as genuinely pressed into the panel. Includes the guardrails that keep the style usable — because the classic failure of this aesthetic is unreadable, un-focusable controls.

Published

Sticky Header with Multi-Column Mega Menu Dropdown — preview
16 / 25Light JS

Sticky Header with Multi-Column Mega Menu Dropdown

Category navigation for a catalogue that does not fit in a list: a full-width panel with grouped columns and a promoted product, opening from a sticky header so it stays reachable at any scroll depth. Built as a disclosure rather than a menu, which is what lets it work identically for pointer, keyboard and touch.

Published

E-Commerce Sticky Header with Search Bar and Cart Badge Counter — preview
17 / 25Light JS

E-Commerce Sticky Header with Search Bar and Cart Badge Counter

The storefront header carrying real work: a persistent search field, account entry and a cart badge that updates as items are added. The demo covers the parts that quietly matter in commerce — announcing the count change to screen reader users, keeping the badge readable at two and three digits, and building a search landmark without a submit-driven form.

Published

Sticky Announcement Bar Stacked Above Sticky Nav (Dual-Stick) — preview
18 / 25Light JS

Sticky Announcement Bar Stacked Above Sticky Nav (Dual-Stick)

Two independently sticky bars that have to cooperate: a promotional strip that scrolls away and a navigation bar that pins beneath it. The demo solves the offset arithmetic properly — each bar's inset is derived from the heights above it, so dismissing the promo re-seats the nav at the top with no leftover gap and no stale scroll padding.

Published

Sticky Sub-Navigation Bar Locked Under the Main Sticky Header — preview
19 / 25Light JS

Sticky Sub-Navigation Bar Locked Under the Main Sticky Header

The second navigation layer that product catalogues and documentation sites need: a filter or category bar that pins directly beneath the main header and stays there while the listing scrolls. Shows the offset arithmetic, the layering, and the visual treatment that keeps two stacked bars from reading as one heavy block.

Published

Sticky Header with Icon-to-Full-Width Search Expand on Click — preview
20 / 25Light JS

Sticky Header with Icon-to-Full-Width Search Expand on Click

Space-saving search for a header that already has too much in it: a magnifier that expands into a full-width field on activation, pushing the navigation aside, then collapses on Escape or blur. The interaction lives or dies on focus management, which is where most implementations fall down.

Published

Sticky Sidebar Table of Contents That Follows a Long Article — preview
21 / 25Light JS

Sticky Sidebar Table of Contents That Follows a Long Article

The On this page rail that documentation sites and long-form editorial layouts are built around: a contents list that pins beside the article, scrolls internally when the outline outgrows the viewport, and keeps the reader's current section marked while they move through the piece.

Published

Mobile Bottom Tab Bar with Safe-Area Inset Padding — preview
22 / 25Light JS

Mobile Bottom Tab Bar with Safe-Area Inset Padding

The thumb-zone navigation that mobile web apps and PWAs are judged on: five destinations pinned to the bottom of the scroll port, spaced above the home indicator instead of underneath it, with hit targets that survive a moving bus. Toggle the simulated inset in the demo to see exactly what breaks on a notched device.

Published

Active-Section Scrollspy Highlighting in a Sticky Navbar — preview
23 / 25Light JS

Active-Section Scrollspy Highlighting in a Sticky Navbar

The one-page marketing site problem: as the visitor scrolls through hero, features, pricing and FAQ, the sticky nav has to say where they are. Built on a single observer with the offset maths that keeps the highlight in step with a sticky header — plus the scroll-end fallback that stops the last section being unreachable.

Published

Sticky Horizontal Scroll Tab Bar with Snap Points — preview
24 / 25Light JS

Sticky Horizontal Scroll Tab Bar with Snap Points

Category rails carry the whole navigation of a menu, a storefront or a news app on a phone: more tabs than fit, pinned to the top of the view, snapping cleanly as a thumb flicks across them. This build pairs the scroll mechanics with the full keyboard tab pattern, so the rail works identically from a trackpad, a thumb and an arrow key.

Published

Sticky Header with Social Share Icons for Articles — preview
25 / 25Light JS

Sticky Header with Social Share Icons for Articles

Publishers put share actions in the sticky chrome because the moment a reader decides to pass an article on is unpredictable. This build keeps a share cluster in the header, adds a vertical rail that appears once the hero is behind the reader, folds to a thumb-reachable bar on phones, and does it without loading a single third-party widget.

Published

FAQ

Frequently asked questions

What is CSS position: sticky and how is it different from position: fixed?
position: sticky is a hybrid: an element behaves as position: relative until its containing block scrolls past a threshold you set (typically top: 0), then it flips to position: fixed and pins to that edge — but ONLY within the bounds of its scroll container / containing block. When the container's bottom scrolls past, the sticky element scrolls away with it. position: fixed, in contrast, pins to the viewport permanently regardless of scroll position or containing block. That difference matters for real product work: a sticky header inside a scrollable article panel stops sticking when the article ends (correct — the header belongs to that panel), while a fixed header overlays every scroll surface on the page (often wrong — it fights modal overlays, embedded scrollers, and any nested scroll container). Sticky also has no layout side-effects when NOT stuck: the reserved space is honored, so content doesn't jump when the flip happens. Every demo in this collection uses position: sticky as the base primitive; fixed is only used for the mobile bottom tab bar (Demo 22) where viewport-pinning IS the intent.
Why does my sticky header sometimes not stick? The overflow:hidden parent gotcha.
This is the #1 sticky-navigation bug. If ANY ancestor between your sticky element and the scroll root has overflow: hidden, overflow: auto, or overflow: scroll, that ancestor becomes the sticky element's scroll container — and the sticky no longer sticks against the viewport. It sticks against that shorter ancestor, which usually means it doesn't visibly stick at all. Common triggers: a card wrapper with overflow: hidden to clip rounded corners, a modal body with overflow-y: auto, a Tailwind class like overflow-clip anywhere in the chain. Fix: remove the overflow rule from the ancestor (usually the fastest fix), OR move the sticky element outside the constrained ancestor, OR change the ancestor's overflow to overflow: visible. Debug: in DevTools, right-click the sticky element → Inspect → search up the ancestor chain for overflow:. Every ancestor is a suspect until proven visible. Every demo in this collection ships with the sticky element as a direct child of body or a scroll-clean container so the bug can't reproduce.
How do I hide a sticky header on scroll-down and reveal it on scroll-up?
The user-friendly "smart" header pattern. Demo 07 is the reference. The core logic: track the previous scroll position in a variable, compare to current on every scroll event, if current > previous → scrolling down → add a hidden class that translates the header up out of view, if current < previous → scrolling up → remove the class. Two production refinements: (1) add a minimum scroll threshold (e.g. if (current < 100) return) so the header always shows in the first viewport, and (2) throttle with requestAnimationFrame so the listener never runs more than once per frame. The CSS side is one transform: translateY(-100%); transition: transform 200ms ease-out — no display: none, no height: 0, because those cause layout jank and destroy focus. Modern browsers also support scroll-timeline as a JS-free alternative, but Safari lags on that as of 2026 — the JS approach is universal today.
How do I build a mobile bottom tab bar that respects the iPhone home indicator?
The iOS "safe area" gotcha. iPhone X and later have a home indicator strip at the bottom of the screen; content painted underneath it is invisible / untappable. CSS solves this with the env(safe-area-inset-bottom) function, which returns the OS-reported inset (34px on newer iPhones, 0 on Android and older devices). Demo 22 is the reference — its bottom tab bar uses padding-block-end: env(safe-area-inset-bottom, 0px) so the tabs sit ABOVE the home indicator, not under it. Two setup steps you can't skip: (1) add <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> to your HTML — WITHOUT viewport-fit=cover, iOS shrinks your layout to avoid the safe area and env() returns 0, so the padding does nothing. (2) Provide the fallback 0px in env(safe-area-inset-bottom, 0px) so browsers that don't support env() (very rare in 2026 — only pre-2020 Firefox / Edge) don't fall back to auto, which is invalid on padding. Android + desktop see zero extra padding; iOS with home indicator gets the correct offset. Zero conditional CSS, zero user-agent sniffing.
How do I add an active-section scrollspy to a sticky navbar?
Scrollspy is the pattern where sticky-nav links auto-highlight as their target sections scroll into view — Demo 23 is the reference. The old jQuery approach used a scroll listener that measured every section's bounding rect on every event: correct, but wasteful. Modern approach: IntersectionObserver with rootMargin tuned to the sticky header's height. Set up one observer with threshold: 0 and rootMargin: '-80px 0px -60% 0px' (top negative offset = sticky header height; bottom -60% = only mark active when the section is in the top 40% of the viewport). Point it at every section. In the callback, on isIntersecting switch, update the nav link's aria-current="true" attribute and let CSS style off that — a[aria-current="true"] { color: var(--accent); border-bottom-color: currentColor }. Never classList.add('active'): aria-current is semantically correct, screen-reader-announced, and doubles as the style hook. Bonus: on nav-link click, smooth-scroll to the target with scrollIntoView({ behavior: 'smooth', block: 'start' }) guarded behind prefers-reduced-motion. The full pattern is 22 lines of JS.
What's the accessible pattern for a sticky mega menu dropdown?
Mega menus (Demo 16) are the highest-risk accessibility surface in a sticky navbar — they layer complex interactive content on top of the page and must remain keyboard, screen-reader, and focus-trap-safe. The reference recipe: (1) The top-level trigger is a real <button type="button"> with aria-expanded="false" and aria-controls="mega-panel-id". (2) The mega panel has role="region" + aria-labelledby pointing at the trigger's ID. (3) On open (click OR keydown Enter/Space), flip aria-expanded to true, remove hidden from the panel, move focus to the FIRST link inside the panel — NOT to the panel itself. (4) Escape key closes the panel AND returns focus to the trigger. (5) Click-outside detection via a bubbling document.click listener that checks !panel.contains(e.target) && e.target !== trigger. (6) Tab from the last link inside the panel closes the panel and moves focus to the next nav element after the trigger. Skip focus trap for mega menus — traps belong to modals; menus should be exit-easy via Escape or Tab. Every interactive element inside the panel needs a visible focus ring (:focus-visible). Grid layout inside the panel needs proper heading structure (<h3> per column) so screen readers can navigate by heading.
How do sticky navigation patterns port to React, Vue, Svelte, Next.js, Tailwind?
The CSS ports unchanged — every .sn-NN selector, every keyframe, every custom property is framework-agnostic. What changes is where the JS lives. React: wrap the scroll listener in useEffect(() => { const cleanup = init(ref.current); return cleanup }, []) so it registers on mount and removes on unmount — never re-register on every render. Vue 3: onMounted(() => init(ref.value)) + onBeforeUnmount for cleanup. Svelte: onMount(() => { init(el); return cleanup }). Next.js App Router: mark the sticky-nav component with 'use client' — sticky positioning is a browser primitive, no SSR value. Tailwind: the class attribute on each demo can be mechanically translated (sticky → sticky, top: 0 → top-0, z-index: 40 → z-40, backdrop-blur → backdrop-blur-md); custom-property tokens become CSS vars in your @theme block. Bootstrap 5: the built-in .sticky-top class covers the base case; layer these demos' custom behaviours on top. Every demo's JS is written as a plain init function (usually 15-40 lines) — strip the IIFE wrapper and call from your framework's lifecycle hook. Zero framework lock-in.

Related collections

32 CSS Accordions — Vertical & Horizontal preview

32 CSS Accordions — Vertical & Horizontal

32 free CSS accordions covering pure-CSS FAQ blocks with details/summary, mobile navigation menus, e-commerce filter sidebars, nested tree views, exclusive single-open groups and smoothly animated height:auto — plus 26 visual variations in vertical, horizontal and hybrid layouts. Copy-paste HTML and CSS, no JavaScript.

39 CSS Breadcrumbs preview

39 CSS Breadcrumbs

39 hand-coded CSS breadcrumbs — Schema.org BreadcrumbList Microdata + WCAG 2.2 accessible (Google Rich Results eligible), :has() responsive collapse, dark/light theme toggle with color-mix, Shopify/Amazon e-commerce filter chip removal, Vercel/Linear/Notion SaaS dashboard app-shell pattern, Docusaurus/Mintlify sticky scroll-shrink header, Amazon-style dropdown sibling menus, NFT/Web3 holographic shimmer (@property + conic-gradient), SaaS marketing gradient text, Airbnb filter chip with container queries, editorial blog wave underline, developer docs one-click path copy (Clipboard API), and 26 more. Semantic HTML: <nav aria-label='Breadcrumb'> + <ol> + aria-current='page'. Framework-agnostic, MIT-licensed.

26 CSS Circular Menus preview

26 CSS Circular Menus

26 hand-coded CSS circular and radial menu designs, from the floating-action FAB speed dial and dashboard radial hubs to game-style pie-slice wheels, SVG gooey metaball fans, hexagonal honeycombs, iris-aperture reveals, orbiting satellites on offset-path, compass-rose directional nav, sci-fi HUD rings, glassmorphism popovers built on the native Popover API, vinyl-record players, and full-takeover nebula overlays on native dialog. Every design uses CSS trigonometry (sin(), cos()) or the counter-rotation trick for positioning, ships real keyboard navigation, aria-labels on icon-only buttons, and a prefers-reduced-motion guard. Copy-paste HTML, CSS and vanilla JS with zero framework dependencies — MIT licensed.

Search CodeFronts

Loading…