/

React Navbar Design: The Patterns Worth Copying

The five navbar shapes that recur across the community catalogue, with the most-bookmarked React component for each, and the focus, keyboard and scroll traps specific to a header.

Serafim Korablev
Serafim Korablev
@korablev

A navbar has one job people keep forgetting: say where you are, then get out of the way. Almost everything shipped is one of five shapes, and choosing between them is mostly a question of how many destinations you have and whether the page underneath is a marketing site or an app.

45 public components on 21st have "navbar" in the name, and that undercounts the category, because half the good ones are filed as a header, a menu or a dock. What follows is the patterns that actually recur, each with the component the community bookmarked most, so you can take a working one instead of restyling the same flex row for the fifth time.

The moving indicator

The most-saved navigation component on 21st is not a full header at all. Tubelight Navbar by Ayushmaan Singh has 3,172 bookmarks: four or five links in a floating pill, with a lit indicator that slides to whichever one is active.

It wins because it answers "where am I" with movement rather than a slightly different grey, and because it survives being dropped on top of any background. Two limits worth knowing before you commit. It stops working past roughly six items, since the pill runs out of width and you are back to a normal bar with a scroll problem. And the indicator is pure decoration to a screen reader, so the active link still needs aria-current, which is covered below.

The conventional bar, which is what most sites need

Logo left, links centred or left, one primary action right. Header 3 by Efferd (993) and Header 2 (868) are the two cleanest versions of it in the catalogue, and they are near the top of the list precisely because that is what most people ship.

Navbar with Dropdowns from Shadcnblocks.com (787) is the one with the menu panels already wired, which is the part people underestimate: the bar is an afternoon, the dropdown is the week. Navbar Menu by Manu Arora (981) is the animated take on the same shape, where hover opens a panel of product cards rather than a list of links.

If you have more than about eight destinations, this family is the only honest answer. Everything else on this page is a way of having fewer.

Decorated menus

Gradient Menu by Le Thanh (1,396) is icons that expand into labels on hover, over a gradient. Glow menu by spoonyvu (769) is the darker version of the same instinct, where the active item carries a soft light instead of a fill.

Both are worth checking against a contrast ratio before shipping. Label text sitting on the light end of a gradient is the most common way a navbar quietly fails WCAG AA, and a glow that reads as emphasis on your monitor often reads as nothing at all on a laptop screen at 40% brightness.

Menus that are not bars

Floating Action Menu by Chetan Verma (1,174), Fluid menu by Deepak Chandwani (933) and Circle Menu by Samit Kapoor (656) are all the same move: one button that expands into its options.

They are good in an app with three or four global actions and a canvas that needs the space. They are a poor fit for a marketing page, for a reason that has nothing to do with taste: a visitor who has never seen your site cannot tell what is inside a closed button, and every navigation now costs an extra click. If you use one publicly, keep the real anchors in the markup rather than rendering them only after the open state flips.

Menu Vertical by berlix (614) is the stacked variant, which is the one that survives being reused as a mobile drawer.

The full-screen overlay

Sterling Gate: Kinetic Navigation by Hardik Kashiyani (1,032) turns the whole viewport into the menu, with the type doing the work. It is the agency and portfolio pattern, and it is the one with the highest cost, because an overlay that covers the page is a modal dialog whether or not you called it one. Everything in the next section applies to it twice.

The traps, roughly in the order they get shipped broken

  1. The mobile drawer is a dialog. Opening it should move focus into the panel, keep Tab inside it, close on Escape, and return focus to the button that opened it. The page behind needs the inert attribute, otherwise a keyboard or screen reader walks straight through the overlay into links nobody can see. The toggle itself must be a real <button> with aria-expanded and aria-controls. A div with an onClick gets none of this for free, which is why building the drawer on a dialog primitive is usually cheaper than it looks.
  2. An active state that exists only as colour. Put aria-current="page" on the active link and style from that attribute, so the two cannot drift apart. In Next.js the comparison comes from usePathname(), and the one bug everyone writes is pathname.startsWith(href) with href="/", which marks the home link active on every route.
  3. A scroll listener that runs every frame. Sticking the header needs no JavaScript at all: position: sticky with a top value does it. For the "has scrolled" boolean that toggles a border or a shadow, put a one-pixel sentinel at the top of the page and watch it with an IntersectionObserver. That is one state change per crossing instead of a React render per scroll event. Separately, backdrop-filter: blur() across a full-width sticky bar repaints a blurred strip on every frame, and on a mid-range Android it is often the single most expensive thing in the scroll path.
  4. Dropdowns that only open on hover. They do not open for a keyboard, and on touch the first tap is swallowed. Open on click and on Enter or Space as well, move between items with the arrow keys, and close on Escape with focus back on the trigger. Add a small delay before closing on mouseleave, or cutting the corner with the cursor kills the panel mid-move.
  5. Anchor links landing underneath the header. A fixed or sticky bar covers the heading you just jumped to. Set scroll-padding-top on the scroll container, or scroll-margin-top on the targets, to the height of the header. And if the page has more than one navigation landmark, give each <nav> its own aria-label, since "navigation" repeated three times helps nobody.

Where else to look

Being honest about the alternatives, because the answer is not always us:

SourceBest forTrade-off
shadcn/uiNavigation Menu and Sheet, styled and in your repoPrimitives, not a finished header; the composition is still yours
Tailwind PlusConventional marketing and app headers with the responsive states donePaid, and every site built from it looks related
Radix PrimitivesThe keyboard, focus and dismiss behaviour, unstyledYou write all the CSS, and it gives you no design at all
21stCommunity navbars, including the animated and kinetic onesQuality varies by author, so preview before you take it

The practical split: take the behaviour from Radix (directly, or through shadcn), and take the look from wherever it already exists.

Taking one

Every component page has a live preview and the code. Installing goes through the shadcn CLI against our registry:

bash

The key comes from your 21st account and installs need a membership, so set API_KEY_21ST once in your shell and the command works for anything in the catalogue. If you would rather not leave your editor, the 21st MCP does the same from Claude, Cursor or Codex: ask for a navbar, get previews inline, and have the agent write the file.

Browse navigation components →

Frequently asked

What makes a good navbar design?
Few enough destinations that they fit on one line, an active state you can see at a glance, and one primary action styled differently from the links so it does not read as a sixth destination. Past roughly eight items a plain bar with dropdown panels is the only layout that still works, and every decorative alternative (a pill with a sliding indicator, a floating button, a full-screen overlay) is really a way of having fewer visible items. Test the bar with the longest label you will ever ship, because translated copy is what usually breaks the spacing.
How do you make a navigation menu accessible?
Put the links in a nav element with its own aria-label when the page has more than one navigation landmark, and mark the current page with aria-current="page" rather than colour alone. The mobile drawer is a dialog: move focus into it, keep Tab inside, close on Escape, return focus to the trigger, and apply the inert attribute to the rest of the page so nothing behind the overlay stays reachable. The toggle must be a real button with aria-expanded and aria-controls, and any dropdown that opens on hover must also open on click and on Enter or Space, or keyboard and touch users never reach it.
How do you build a sticky header without hurting scroll performance?
Sticking the header needs no JavaScript at all: position: sticky with a top value does it. For the "has scrolled" flag that adds a border or shadow, watch a one-pixel sentinel element at the top of the page with an IntersectionObserver, which fires once per crossing instead of re-rendering on every scroll event. Be careful with backdrop-filter: blur() on a full-width bar, since it repaints a blurred strip on every frame and is often the most expensive thing in the scroll path on mid-range Android.
Where can I find React navbar components?
21st has 45 public components with navbar in the name as of August 2026, plus many more filed as headers, menus and docks, all browsable with a live preview at 21st.dev/community/components/s/navigation-menu. shadcn/ui covers the Navigation Menu and Sheet primitives underneath a header, and Radix Primitives gives you the keyboard and focus behaviour unstyled if you would rather write the CSS yourself. Installing from 21st runs through the shadcn CLI (npx shadcn@latest add with a registry URL), which needs a 21st API key and a membership.

Published

Aug 19, 2026

Read time

6 min

Tags

GuideNavigationReact

Share