Navigation menu
A navigation menu is a site's or app's main navigation: a row of links where some items open a panel of more links.
Analytics Billing
<tk-navigation-menu label="Main">
<tk-navigation-menu-item>
Products
<ul slot="panel">
<li><tk-link href="/analytics" treatment="quiet">Analytics</tk-link></li>
<li><tk-link href="/billing" treatment="quiet">Billing</tk-link></li>
</ul>
</tk-navigation-menu-item>
<tk-navigation-menu-item href="/pricing">Pricing</tk-navigation-menu-item>
<tk-navigation-menu-item href="/docs" current>Docs</tk-navigation-menu-item>
</tk-navigation-menu>Anatomy
| Part | What it is |
|---|---|
tk-navigation-menu |
a <nav> landmark holding a list of items |
tk-navigation-menu-item with href |
a link |
tk-navigation-menu-item with a panel |
a button that opens the panel; a chevron shows it |
| panel | a floating surface with your links; you decide its layout |
An item is a link or a button, never both. With both href and a panel, the panel wins.
There is no disabled: to make an item not a link, leave out href.
Panels
The panel's content is yours. For a short dropdown, write a list of
Guides Blog
<tk-navigation-menu label="Main">
<tk-navigation-menu-item>
Resources
<ul slot="panel">
<li><tk-link href="/guides" treatment="quiet">Guides</tk-link></li>
<li><tk-link href="/blog" treatment="quiet">Blog</tk-link></li>
</ul>
</tk-navigation-menu-item>
</tk-navigation-menu>For a larger panel, lay out columns, each with a heading and a list:
Analyze
Dashboards
Operate
Billing
<tk-navigation-menu label="Main">
<tk-navigation-menu-item>
Products
<div slot="panel" style="display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-24)">
<div><h3>Analyze</h3><ul><li><tk-link href="/dashboards" treatment="quiet">Dashboards</tk-link></li></ul></div>
<div><h3>Operate</h3><ul><li><tk-link href="/billing" treatment="quiet">Billing</tk-link></li></ul></div>
</div>
</tk-navigation-menu-item>
</tk-navigation-menu>- Put only links in a panel. No buttons, actions, or form fields.
- Don't put a panel inside a panel.
- The panel is at most 720px wide and 560px tall, and scrolls past that.
Opening
- A click,
Enter, orSpaceon an item opens its panel.Downopens it and moves to its first link. - Hovering opens it after a short delay, so a pointer passing by doesn't flash it open. The pointer can move diagonally to the panel without closing it.
- Focus alone never opens a panel, and neither does a touch-hover.
- One panel is open at a time.
Esc, a click outside, the pointer leaving, or focus leaving the menu closes it. It never closes on a timer.
Current page
current marks the page people are on. The item gets a 2px underline and stays a link.
<tk-navigation-menu label="Docs sections"> <tk-navigation-menu-item href="/guides">Guides</tk-navigation-menu-item> <tk-navigation-menu-item href="/components" current>Components</tk-navigation-menu-item> <tk-navigation-menu-item href="/tokens">Tokens</tk-navigation-menu-item> </tk-navigation-menu>
States
At rest, items are muted. Hover and keyboard focus darken an item and underline its label; focus also shows a ring. An item with an open panel stays dark and its chevron turns over.
Mobile
The navigation menu has no breakpoint of its own. On narrow screens, put the same links in
a
When to use
- Use a navigation menu for main navigation across the top of every page.
- Use a
Sidebar when the navigation is a tall column beside the page. - Use a
Menu for actions such as Duplicate or Sign out. Every item in a navigation menu goes to a page. - Use a
Tab bar to switch sections within one page. - Use a
Breadcrumb to show where a page sits; it goes alongside the navigation menu, not in its place. - Use one level of panels. For deeper hierarchies, use a Sidebar or a
Tree .
Content
- Name each item for its page or group, in one or two words: "Pricing", "Products".
- Keep panel links short, in sentence case.
- Name the landmark without the word "navigation":
label="Main", not "Main navigation".
Do / Don't
| ✅ Do | ❌ Don't |
|---|---|
| Put links in panels | Put "Sign out" or "Delete" in a panel; use a menu |
| Use one level of panels | Open a panel from inside a panel |
Give each <nav> its own label |
Put "navigation" in the label |
| Make an item a link or a panel button | Give an item both href and a panel |
| Use a Sheet on narrow screens | Squeeze the row onto a phone screen |
Related
Sidebar : main navigation in a column; nested rows open in place.Menu : actions.Tab bar : sections within one page.Breadcrumb : where a page sits.Link : the quiet links inside panels.
API
tk-navigation-menu
| Attribute | Type | Default | What it does |
|---|---|---|---|
label |
string | Main |
the landmark's accessible name |
| Slot | Content |
|---|---|
| default | tk-navigation-menu-item elements, in reading order |
tk-navigation-menu-item
| Attribute | Type | Default | What it does |
|---|---|---|---|
href |
string | — | makes the item a link |
target |
string | — | the link's target |
rel |
string | — | the link's rel |
current |
boolean | false |
the page people are on: aria-current="page" and the underline |
open |
boolean | false |
read-only: whether the panel is open |
| Slot | Content |
|---|---|
| default | the item's label |
panel |
the panel content; it makes the item a button |
Events
| Event | Detail | Cancelable | When |
|---|---|---|---|
tk-toggle |
{ open, item } |
yes | before a panel opens or closes; cancel it to control panels yourself |
It fires on tk-navigation-menu.
CSS
tk-navigation-menu::part(list): the<ul>row.tk-navigation-menu-item::part(trigger): the item's button or link.tk-navigation-menu-item::part(panel): the panel.
Tokens
| Part | Tokens |
|---|---|
| item | text/secondary, Label Medium (14/20) |
| item, hover / focus / open | text/default; hover and focus underline the label |
| current item | text/default + a 2px border/selected underline |
| panel | surface/raised + shadow-2, radius-16, space-12 padding; border/default in high contrast |
| focus ring | border/accent/focus |
Values per theme:
Accessibility
Built in:
- A named
<nav>landmark around a real list. - Items with panels are real buttons with
aria-expanded; no menu roles, as the ARIA pattern for site navigation asks. - The open panel stays in the reading order right after its button, and Tab moves through its links.
currentsetsaria-current="page"; the underline marks it without color.- Panels opened by hover stay open while the pointer is on them, close with
Esc, and don't time out. - With reduced motion, the chevron turns without animation.
Your part:
- Give every
<nav>on the page a differentlabel, such as "Main" and "Breadcrumb". - Write real
<ul>and<li>in a dropdown so it reads as a list. - Put only links in panels.
| Key | Action |
|---|---|
Tab |
moves through the items and, when a panel is open, through its links |
Enter / Space |
on an item with a panel: opens or closes it |
Esc |
closes the panel and returns focus to its item |
Right / Left |
moves to the next or previous item |
Down |
on an item with a panel: opens it and moves to its first link |
Home / End |
moves to the first or last item |
The arrow keys add to Tab; every item and link stays a Tab stop.