Navigation Bar
A navigation bar lets people switch between a small number of top-level destinations, and can hide as the page scrolls.
<md-gb-nav-bar aria-label="Primary">
<md-gb-nav-bar-item active href="#home">
<md-gb-icon slot="icon">home</md-gb-icon>
Home
</md-gb-nav-bar-item>
<md-gb-nav-bar-item href="#explore">
<md-gb-icon slot="icon">explore</md-gb-icon>
Explore
</md-gb-nav-bar-item>
<md-gb-nav-bar-item href="#library">
<md-gb-icon slot="icon">library_music</md-gb-icon>
Library
</md-gb-nav-bar-item>
<md-gb-nav-bar-item href="#profile">
<md-gb-icon slot="icon">person</md-gb-icon>
Profile
</md-gb-nav-bar-item>
</md-gb-nav-bar>Install with shadcn/ui: npx shadcn@latest add https://material-web.dev/3.0/r/md-nav-bar.json (setup)
Usage guidelines
Link to “Usage guidelines”- Use it in compact and medium windows. From expanded windows up, switch to a navigation rail.
- Keep three to five destinations. They should be of equal importance.
- Keep destinations consistent. The same destinations appear on every screen of the app.
- Pick the item layout. Use vertical items in compact windows and horizontal items from medium windows.
This component is new in M3 Expressive.
Anatomy
Link to “Anatomy”A navigation bar holds items. Each item has an icon, a label and an optional badge.
<md-gb-nav-bar aria-label="Chat">
<md-gb-nav-bar-item active>
<md-gb-icon slot="icon">chat_bubble</md-gb-icon>
<md-gb-badge slot="badge">3</md-gb-badge>
Chats
</md-gb-nav-bar-item>
<md-gb-nav-bar-item>
<md-gb-icon slot="icon">call</md-gb-icon>
Calls
</md-gb-nav-bar-item>
</md-gb-nav-bar>Examples
Link to “Examples”Item layout
Link to “Item layout”Set item-layout to vertical (the default) or horizontal. With auto, items are vertical in compact windows and horizontal from 600px.
<md-gb-nav-bar item-layout="horizontal" aria-label="Library">
<md-gb-nav-bar-item active>
<md-gb-icon slot="icon">auto_awesome</md-gb-icon>
For you
</md-gb-nav-bar-item>
<md-gb-nav-bar-item>
<md-gb-icon slot="icon">bookmark</md-gb-icon>
Saved
</md-gb-nav-bar-item>
<md-gb-nav-bar-item>
<md-gb-icon slot="icon">settings</md-gb-icon>
Settings
</md-gb-nav-bar-item>
</md-gb-nav-bar>Badges
Link to “Badges”Set badge on an item to show a count, or badge="dot" for a small dot that signals something new.
<md-gb-nav-bar aria-label="Mail">
<md-gb-nav-bar-item active badge="4">
<md-gb-icon slot="icon">mail</md-gb-icon>
Inbox
</md-gb-nav-bar-item>
<md-gb-nav-bar-item badge="dot">
<md-gb-icon slot="icon">chat_bubble</md-gb-icon>
Chat
</md-gb-nav-bar-item>
<md-gb-nav-bar-item>
<md-gb-icon slot="icon">videocam</md-gb-icon>
Meet
</md-gb-nav-bar-item>
</md-gb-nav-bar>Links
Link to “Links”Give an item an href (and optionally target and rel) to make the destination a link, as in the first example. The item then has the link role and the selected one is marked aria-current="page". Without href an item is a tab that just reports the selection.
Hide on scroll
Link to “Hide on scroll”Set scroll-behavior="hide" to hide the bar when the page scrolls down and show it again on scroll up. By default it follows the window; set scroll-target to the id of another scrolling element. Fix the bar to the bottom of the page.
Message 1
Message 2
Message 3
Message 4
Message 5
Message 6
Message 7
Message 8
<div id="messages">
<p>Message 1</p>
<p>Message 2</p>
<p>Message 3</p>
<p>Message 4</p>
<p>Message 5</p>
<p>Message 6</p>
<p>Message 7</p>
<p>Message 8</p>
<md-gb-nav-bar scroll-behavior="hide" scroll-target="messages" aria-label="Mail">
<md-gb-nav-bar-item active>
<md-gb-icon slot="icon">inbox</md-gb-icon>
Inbox
</md-gb-nav-bar-item>
<md-gb-nav-bar-item>
<md-gb-icon slot="icon">send</md-gb-icon>
Sent
</md-gb-nav-bar-item>
</md-gb-nav-bar>
</div>#messages {
inline-size: 100%;
block-size: 240px;
overflow: auto;
}
md-gb-nav-bar {
position: sticky;
inset-block-end: 0;
}Selection
Link to “Selection”The active item shows the current destination, and selected-index selects an item by position. The bar fires change when the selection changes.
<md-gb-nav-bar aria-label="Sections">
<md-gb-nav-bar-item active>
<md-gb-icon slot="icon">home</md-gb-icon>
Home
</md-gb-nav-bar-item>
<md-gb-nav-bar-item>
<md-gb-icon slot="icon">search</md-gb-icon>
Search
</md-gb-nav-bar-item>
<md-gb-nav-bar-item>
<md-gb-icon slot="icon">settings</md-gb-icon>
Settings
</md-gb-nav-bar-item>
</md-gb-nav-bar>
<output id="selection" role="status">Selected item 0</output>const bar = document.querySelector('md-gb-nav-bar')!;
const selection = document.querySelector('#selection')!;
bar.addEventListener('change', () => {
selection.textContent = 'Selected item ' + bar.selectedIndex;
});Accessibility
Link to “Accessibility”- Give the bar an
aria-labelsuch as "Primary navigation". - Without links the bar is a tab list and its items are tabs, with exactly one selected. Tab moves focus into the bar, the arrow keys move between items, and Enter and Space select one.
- When the items have an
hrefthe bar is a navigation landmark of links and the selected one isaria-current="page". Enter follows a link; Space doesn't. - Every item needs a visible label, which is also its accessible name. If the label is ambiguous, add a more descriptive
aria-labelto the item. - A hidden bar never hides while focus is inside it or when the page scrolls from a key press, and it reappears when focus moves into it. Leave
scroll-behavioroff if screen reader users rely on the bar. - Disabled items leave the tab order.
Compatibility
Link to “Compatibility”Material Design 3Spec checked88% tokens
80 of 259 buildable spec units are tested, 24 are excluded with a written reason and 0 are uncovered (the target is 0). 35 of 40 token declarations match the spec (88%), and 5 have no spec token.
navigation-bar on m3.material.io (opens in a new tab) How compliance is measured
BaselineWidely availableChrome 124Edge 124Firefox 125Safari 17.4
The component’s own CSS and JavaScript rely only on web platform features that are Baseline widely available: it works in Chrome 124, Edge 124, Firefox 125, Safari 17.4 and later.
Newer features it uses where the browser has them (progressive enhancements):
- Cursor styles (opens in a new tab) Limited availability degrades safely where it is missing
- user-select (opens in a new tab) Limited availability used inside an
@supportsguard
Browser support Learn more about Baseline (opens in a new tab)
WAI-ARIAaxe and ARIA 1.3 passButtonTabs
Roles the component renders: button (opens in a new tab), navigation (opens in a new tab), tablist (opens in a new tab).
Follows the WAI-ARIA Authoring Practices: Button (opens in a new tab), Tabs (opens in a new tab).
4 rendered states run through axe-core and the WAI-ARIA 1.3 role and attribute rules in a real browser, with no known gaps.
WAI-ARIA 1.3 (opens in a new tab) ARIA Authoring Practices (opens in a new tab) Accessibility
Lighthouse98 · 100 · 100 · 100
Performance Accessibility Best practices SEO
Audits under 90:
- Eliminate render-blocking resources
- Minify JavaScript
- Enable text compression
- Document request latency
- Network dependency tree
- Render blocking requests
Lighthouse 12.8.2 (desktop, 2026-11-08) on the component alone: its first example on a page of its own, without this site's shell. The modules are the development build (not bundled or minified), so the performance score is indicative.
API reference
Link to “API reference”<md-gb-nav-bar>
Link to “<md-gb-nav-bar>”A Material Design gBreeze navigation bar custom element.
Properties
Link to “Properties”| Property | Attribute | Type | Default |
|---|---|---|---|
autoSelectWhether or not to automatically select a tab when it is focused. |
autoselect |
boolean |
false |
itemLayoutThe layout orientation of items: vertical, horizontal, or auto (vertical in compact windows, horizontal from medium windows, 600px). |
item-layout |
NavBarLayout |
'vertical' |
orientationOrientation of the tablist ('horizontal' or 'vertical'). |
orientation |
"horizontal" |
"vertical" |
scrollBehaviorHow the bar reacts to scrolling: hide hides it on scroll down. |
scroll-behavior |
"hide" |
|
scrollTargetThe id of the element whose scrolling drives scroll-behavior. Defaults to the window. |
scroll-target |
string |
'' |
selectedIndexThe 0-based index of the currently active navigation bar item. Alias for selectedTabIndex. |
selected-index |
number |
|
selectedTabIndexThe index of the currently selected tab. |
selectedtabindex |
number |
Slots
Link to “Slots”| Slot | Description |
|---|---|
| default | Used to display navigation bar items (md-gb-nav-bar-item). |
Events
Link to “Events”| Event | Description |
|---|---|
changeEvent |
Fired when the selected navigation bar item changes. |
CSS parts
Link to “CSS parts”| Part | Description |
|---|---|
::part(nav-bar) |
The navigation bar's root container. |
CSS custom properties
Link to “CSS custom properties”| Property | Description |
|---|---|
--container-color |
|
--container-elevation |
|
--container-height |
|
--container-shadow-color |
|
--container-shape |
|
--item-active-icon-color |
|
--item-active-indicator-color |
|
--item-active-indicator-height |
|
--item-active-indicator-icon-label-space |
|
--item-active-indicator-leading-space |
|
--item-active-indicator-shape |
|
--item-active-indicator-trailing-space |
|
--item-active-indicator-width |
|
--item-active-label-text-color |
|
--item-active-state-layer-color |
|
--item-between-space |
|
--item-container-between-space |
|
--item-icon-size |
|
--item-inactive-icon-color |
|
--item-inactive-label-text-color |
|
--item-inactive-state-layer-color |
|
--item-label-text |
|
--item-label-text-axes |
|
--item-label-text-tracking |
|
--motion-duration |
|
--motion-easing |
<md-gb-nav-bar-item>
Link to “<md-gb-nav-bar-item>”A Material Design gBreeze navigation bar item custom element.
Properties
Link to “Properties”| Property | Attribute | Type | Default |
|---|---|---|---|
activeWhether the navigation bar item is active. Alias for selected. |
active |
boolean |
|
badgeOptional badge text (or 'dot' / 'true' for a small dot badge). |
badge |
string |
'' |
disabledWhether the navigation bar item is disabled. |
disabled |
boolean |
false |
hrefThe URL the destination links to. The item is then a link (role link, aria-current="page" while selected) instead of a tab. |
href |
string |
'' |
itemLayoutThe layout orientation of the item ('vertical' or 'horizontal'). |
item-layout |
NavBarItemLayout |
'vertical' |
labelOptional label text if not provided via default slot. |
label |
string |
'' |
relThe link's rel attribute, when href is set. |
rel |
string |
'' |
tabpanelID of the associated md-aria-tabpanel element. |
tabpanel |
string |
|
targetWhere to open the linked href, e.g. _blank. |
target |
"" |
"_blank" |
unfilledIconWhether the icon has no filled style. The active destination then uses the semibold icon weight instead of the filled icon. |
unfilled-icon |
boolean |
false |
Slots
Link to “Slots”| Slot | Description |
|---|---|
| default | Used to display the item's label text. |
badge |
Used to display a custom badge on the item's icon. |
icon |
Used to display the item's icon (md-gb-icon). |
Methods
Link to “Methods”| Method | Description |
|---|---|
click() => void |
Activates the destination: follows its link, else clicks the tab. |
CSS parts
Link to “CSS parts”| Part | Description |
|---|---|
::part(indicator) |
The active indicator / icon container element. |
::part(label) |
The label text container element. |
::part(nav-bar-item) |
The navigation bar item's presentational container. |