NavBar
The bar across the top of a page: the brand, menus that open in one morphing panel, and the calls to action, static, sticky or auto-hiding.
import { NavBar } from "@butteryui/react";Demo
Decks for every meeting
Written in an afternoon, ready for any screen.
Features
Room to scroll, so the bar can show what it does.
Themes
Room to scroll, so the bar can show what it does.
Export
Room to scroll, so the bar can show what it does.
When to use it
Use it for
- The top of a marketing, docs or help site
- A page whose sections need menus of links
Not for
- App screens: use HeaderBar in an AppShell
- Links to the sections of one page: use SubNav under the nav bar
Examples
Floating bar
A floating bar: its row a rounded surface inset from the page's top and sides, its sheet the same as ever.
Help site
A help site's bar: one menu, a link and a single call to action, folding into the Menu button on a narrow page.
Links only
A bar of plain links with no menus, and a call to action with the forward arrow.
Site header
The top of a landing page: the brand, a menu with a story and a See all link, a plain link, and two calls to action over the opening.
Decks for every meeting
Written in an afternoon, ready for any screen.
With search
A guide site's bar with a search after its menus, which narrows first as the bar runs out of room and stays when the menus fold.
Showing every guide
Variants and states
Sticky
64px on the page container, with no background over the hero. Its menus open in one MorphMenu card just under the bar while the page blurs. Scrolled, it stays pinned on the panel surface. Narrow the page and everything folds into the menu button.
Decks for every meeting
Written in an afternoon, ready for any screen.
Features
Room to scroll, so the bar can show what it does.
Themes
Room to scroll, so the bar can show what it does.
Export
Room to scroll, so the bar can show what it does.
Auto-hide
Slides away on spring.smooth as the page scrolls down and comes back as it scrolls up, publishing how far it has gone as --bt-sticky-shift for a SubNav under it.
Decks for every meeting
Written in an afternoon, ready for any screen.
Features
Room to scroll, so the bar can show what it does.
Themes
Room to scroll, so the bar can show what it does.
Export
Room to scroll, so the bar can show what it does.
Floating
variant floating draws the row as a rounded surface 12px under the top, inside the page container, its shadow deepening once the page scrolls under it. It stays sticky or hides itself as a plain bar does, and folds into the same sheet.
Decks for every meeting
Written in an afternoon, ready for any screen.
Features
Room to scroll, so the bar can show what it does.
Themes
Room to scroll, so the bar can show what it does.
Export
Room to scroll, so the bar can show what it does.
Props
NavBar
| Prop | Type | Default | Description |
|---|---|---|---|
brand | ReactNode | The start of the bar: the product's mark and name, usually a link home. | |
search | ReactNode | A search after the menus, before the actions: a CommandSearch or a soft SearchField, at most 360px,
narrowing before the menus fold. It stays in the bar, before the menu button, when they do. | |
actions | ReactNode | The end of the bar: a secondary pill and a primary call to action with arrow="forward". | |
pinned | ReactNode | Actions that stay in the bar when it folds, just before the menu button, such as a store's bag or a
notification bell, as icon buttons or small pills. Unfolded, they follow actions. | |
behavior | "static" | "sticky" | "auto-hide" | "static" | "static" (the default) scrolls away with the page; "sticky" stays pinned; "auto-hide" slides away
as the page scrolls down and comes back as it scrolls up. Pinned and scrolled, it takes the panel
surface with shadow-card. |
variant | "plain" | "floating" | "plain" | How it's drawn: "plain" (the default), across the top with no background at rest; or "floating", its
row a rounded surface (r16, padded 16) with a shadow that deepens once the page scrolls under it, 12px
below the window's top and inside the page container's side padding (12px from the window's sides when
not contained). Its behavior, its menus and its sheet work as they do plain. |
label | string | "Main" | Names the navigation for screen readers. Defaults to "Main". |
contained | boolean | true | Whether the bar sits on the page container (1200px at most, centered). Defaults to true; turn it off
for an app's own chrome, which spans its window. |
menuLabel | string | "Menu" | Names the button that opens the menu on narrow pages. Defaults to "Menu". |
closeLabel | string | "Close menu" | Names the button that closes it. Defaults to "Close menu". |
skipTo | string | The id of the page's main content. With it, the first thing Tab reaches is a link there, shown over the bar's start only while it has focus, so keyboard users can skip the bar and any navigation after it. | |
skipLabel | string | "Skip to content" | Names the link skipTo adds. Defaults to "Skip to content". |
children | ReactNode | The menus and links: MorphMenu.Items and MorphMenu.Links. | |
style | MotionStyle | Inline styles, which can include motion values. |
It also takes Omit<ComponentPropsWithRef<"header">, "onAnimationStart" | "onDrag" | "onDragStart" | "onDragEnd" | "style">.
Accessibility
A banner landmark holding a navigation named "Main". The menus work as MorphMenu's do. With little room, a "Menu" button opens a modal sheet with the same menus as sections, and Escape closes it.
| Keys | What they do |
|---|---|
| Tab | With skipTo, reaches Skip to content first; Enter on it moves on to the page's main content |
| Enter or Space | Opens or closes the focused trigger's menu, or on a narrow page opens the sheet from Menu |
| Arrow keys | Move between the triggers and links in the bar, or between the sections in the sheet |
| Down arrow | Opens the focused trigger's menu, or moves into it once it's open |
| Escape | Closes the open menu, or the sheet, and puts focus back on its trigger or on Menu |
| Tab | Goes from an open trigger into its menu and on along the bar; in the sheet it stays inside until the sheet closes |
Motion
It changes shape as one surface, on `spring.smooth`, or `spring.morph` for a big change, rather than closing and reopening.
With reduced motion: Its menus fade in and out in 100ms and take each menu's size and place at once, as MorphMenu's do; the blur behind them and the sheet fade in and out in 100ms, the sheet without rising; and auto-hide shows and hides the bar at once, a floating one with its inset and shadow.
Layout
It's 64px tall (--bt-h-nav-bar) across its container, with its content on the page container, 1200px at most, unless contained is false: the brand at the start, the menus beside it and the actions at the end, never wrapping. Under 640px of its own width, or once the menus and actions no longer fit beside the brand, they fold into a Menu button that opens a full-height sheet 8px inside the window; a menu opens in one card 8px under the bar, never over it, and scrolls inside when it's taller than the room below. With variant floating the row is a rounded surface (r16, padded 16) 12px under the top, inside the page container's side padding or 12px from the window's sides when not contained, so the bar takes 76px and publishes that as --bt-sticky-top; it folds by the room inside the row's padding.
Related
See it in the Halfmoon shop demo.