Hide on Scroll Bar

About this block

Hide on Scroll BarPRO

A sticky store bar that slides away while you scroll down, returns as soon as you scroll up and shrinks from 64 to 56 pixels once the page moves. Shop drops a full-width panel of three link columns, and on a phone the menu is a floating bottom pill of icon links whose Menu button grows a card above it; the pill hides on scroll down too. Panels stay in the markup and are toggled with CSS.

A sticky store bar that gets out of the way: it slides up while you scroll down, comes straight back when you scroll up, and shrinks from h-16 to h-14 once the page has moved. Shop drops a full-width panel of three link columns. On a phone the navigation is a floating pill at the bottom of the screen with icon links and a Menu button that grows a card of shop links above it; the pill hides on scroll down along with the bar. The block renders a tall demo body so the behaviour can be scrolled.

Upgrade to Pro

Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.

Upgrade Now

Installation

Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.

Radix flavor

bash
npx shadcn add "https://beste.dev/r/navbar112?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://beste.dev/r-base/navbar112?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/navbar112.tsx plus the shadcn button primitive it uses.

Quick start

The installed file exports navbar112Demo alongside the block: the exact props behind the preview above. Spread it to get a working navbar in one line.

tsx
import { Navbar112, navbar112Demo } from "@/components/beste/block/navbar112";

export default function Page() {
  return <Navbar112 {...navbar112Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Navbar112 } from "@/components/beste/block/navbar112";

export default function Page() {
  return (
    <Navbar112
      brand="Harbor"
      shop={{
        label: "Shop",
        columns: [
          { title: "Footwear", links: [{ label: "Runners", href: "/runners" }, { label: "Trail", href: "/trail" }] },
          { title: "Accessories", links: [{ label: "Watches", href: "/watches" }, { label: "Bags", href: "/bags" }] },
        ],
      }}
      links={[
        { label: "Journal", href: "/journal" },
        { label: "Stores", href: "/stores" },
      ]}
      actions={[{ label: "Bag (2)", href: "/bag", variant: "outline" }]}
      tabs={[
        { icon: "home", label: "Home", href: "/" },
        { icon: "bag", label: "Bag", href: "/bag" },
      ]}
      labels={{ open: "Open menu", close: "Close menu", menu: "Menu" }}
    />
  );
}

Leave sections empty in a real layout; it only fills the preview with scrollable content.

Props

PropTypeDefaultDescription
brandstring–Wordmark on the left
shopShopMenu–The item that opens the three-column panel
linksNavItem[][]Plain links beside it, repeated in the mobile card
actionsActionButton[][]Buttons on the right of the bar
tabsTab[][]Icon links in the mobile bottom pill
sectionsDemoSection[][]Demo body rendered under the bar so the page scrolls
labels{ open?: string; close?: string; menu?: string }{}Accessible names and the visible label of the mobile Menu button
classNamestring–Extra classes for the outer wrapper
ts
type ShopMenu = {
  label: string;
  columns: ShopColumn[];
};

type ShopColumn = {
  title: string;
  links: NavItem[];
};

type Tab = {
  icon: "home" | "search" | "bag" | "heart" | "user";
  label: string;
  href: string;
};

type DemoSection = {
  heading: string;
  description: string;
  image?: { src: string; alt: string };
};

type NavItem = {
  label: string;
  href: string;
};

type ActionButton = {
  label: string;
  href: string;
  variant?: "default" | "outline" | "ghost" | "secondary";
};

Behavior notes

  • The shop panel and the mobile menu card are always rendered and toggled with CSS classes, so every link is in the server-rendered HTML. Closed panels carry aria-hidden and inert.
  • A passive scroll listener compares the current position with the last one: moving down past 96 pixels hides the bar and the bottom pill with a translate, moving up shows them again, and changes under 6 pixels are ignored.
  • The bar height switches from h-16 to h-14 with a height transition as soon as the page has scrolled 24 pixels.
  • Hiding the bar on scroll also closes the shop panel and the mobile card, and the hidden pill is inert so it cannot be reached by keyboard.
  • The Shop trigger opens on hover and on click with aria-expanded and aria-controls; it closes on mouse leave, Escape and a pointer down outside the header. Links in the mobile card close it on click.

More Navigation blocks

View all Navigation
PRO

navbar102

Sticky Sub-Nav Pills

PRO

navbar103

Single Menu Tabs Panel

PRO

navbar97

Dismissible Announcement Mega

Get Pro