Hide On Scroll Navbar
A navbar that slides away on scroll-down and reappears on scroll-up.
- Category
- Patterns
- Added
- 2026-08-24
- Deps
- 1
- Updated
- 2026-09-01
Section content line 1
Section content line 2
Section content line 3
Section content line 4
Section content line 5
Section content line 6
Section content line 7
Section content line 8
Section content line 9
Section content line 10
Section content line 11
Section content line 12
Section content line 13
Section content line 14
Props
This entry takes no configurable props.
"use client";
import { useRef, useState } from "react";
import { motion, useMotionValueEvent, useScroll } from "framer-motion";
export function HideOnScrollNavbar({ children }: { children?: React.ReactNode }) {
const { scrollY } = useScroll();
const [hidden, setHidden] = useState(false);
const [inert, setInert] = useState(false);
const lastY = useRef(0);
useMotionValueEvent(scrollY, "change", (y) => {
const diff = y - lastY.current;
if (Math.abs(diff) > 4) {
const nextHidden = diff > 0 && y > 40;
if (!nextHidden) setInert(false);
setHidden(nextHidden);
lastY.current = y;
}
});
return (
<motion.div
animate={{ y: hidden ? "-100%" : "0%" }}
transition={{ duration: 0.25, ease: [0.65, 0, 0.35, 1] }}
onAnimationComplete={() => {
if (hidden) setInert(true);
}}
inert={inert}
className="fixed inset-x-0 top-0 z-40 flex items-center justify-between border-b border-neutral-200 bg-white/90 px-6 py-3 backdrop-blur-sm"
>
{children ?? <span className="font-bold">Brand</span>}
</motion.div>
);
}
About this pattern
The pattern is reclaiming vertical space on scroll without losing the nav entirely: hide it on the way down, bring it back the instant the user scrolls up, which is usually a sign they're hunting for something rather than just reading. Reach for it over a plain sticky navbar on long-form or content-dense pages where the header is competing for screen space; reach for a simpler shrink-on-scroll or fade-to-translucent treatment instead if hiding it outright would make navigation feel unreliable, like inside a checkout flow. Direction comes from diffing the current scrollY against a value held in a ref rather than state, inside a Framer Motion useMotionValueEvent listener — a ref avoids triggering a render on every scroll tick, and useScroll already batches internally to animation frames, so no extra throttling is needed on top. A 4px delta threshold absorbs jitter from trackpads and momentum scrolling so the bar doesn't flicker open and shut on tiny movements, and hidden only flips true past y > 40, so scrolling down from the very top never immediately hides it. One real gap between the two files: the shipped code tracks window scroll, exactly what a page header needs, while the preview scopes useScroll to its own container since it's a demo inside a scrollable card — don't carry that container-scoped version into a real header.
Curator’s note
The live preview scopes useScroll to its own scrollable card (useScroll({ container })) since this is an isolated demo, not the page; the shipped code above tracks window scroll instead, which is what a real site header needs.
Pairs well with
Matched on shared tags and category — the entries most likely to be used alongside this one.
Sticky Scroll Stack
patternsCards that pin and stack on top of each other as you scroll past.
Chapter Progress Nav
componentsA sticky section nav whose items fill like progress bars as you read — and still reaches the short last section that fixed-line navs never activate.
Scroll Card Deal
animationsA pile of cards that fans out symmetrically as its section crosses the viewport.