Tab bar
The main destinations of a small-screen app, along the bottom edge.
On this page
A tab bar holds the three to five main destinations of a small-screen app, along the bottom edge where the thumb rests. Each item is an icon over a short label. The current one is in ink and its icon rests on a soft pill; nothing else in the bar has a hue. The bar is a pane of frosted glass with a hairline above it, and it keeps clear of the home indicator.
Tab bar
<div class="well h(320) max-w(380) mx-auto overflow-y-auto"> <div class="grid gap-sm p-md"> <div class="sheet p-lg text-sm">Today</div> <div class="sheet p-lg text-sm">Continue reading</div> <div class="sheet p-lg text-sm">New this week</div> <div class="sheet p-lg text-sm">From your library</div> </div> <nav class="tabbar" aria-label="Main"> <a class="tabbar-item" href="#" aria-current="page"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <path d="M4 11l8-7 8 7v8a1 1 0 0 1-1 1h-4v-6h-6v6H5a1 1 0 0 1-1-1z" /> </svg> <span class="tabbar-label">Home</span> </a> <a class="tabbar-item" href="#"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <circle cx="11" cy="11" r="6" /> <path d="m20 20-4-4" /> </svg> <span class="tabbar-label">Search</span> </a> <a class="tabbar-item" href="#"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <path d="M5 5h14v14H5zM9 9h6M9 13h6" /> </svg> <span class="tabbar-label">Library</span> </a> <a class="tabbar-item" href="#"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <circle cx="12" cy="9" r="3.5" /> <path d="M5 20c1-4 4-5 7-5s6 1 7 5" /> </svg> <span class="tabbar-label">Profile</span> </a> </nav></div>The bar is position: sticky at the bottom of its scroll container. In an app shell that does not scroll as a whole, put it after the scrolling region instead; it draws the same.
The tab bar is the bar itself. Where it sits among the regions of a page is a layout's decision: in a page it follows the main region, and in a fixed shell it takes the footer.
#Floating
tabbar-floating lifts the bar off the edge with a margin and a surface's corner, over a floating shadow.
Floating
<div class="tray h(320) max-w(380) mx-auto p(0) overflow-y-auto"> <div class="grid gap-sm p-md"> <div class="sheet p-lg text-sm">Today</div> <div class="sheet p-lg text-sm">Continue reading</div> <div class="sheet p-lg text-sm">New this week</div> <div class="sheet p-lg text-sm">From your library</div> </div> <nav class="tabbar tabbar-floating" aria-label="Main"> <a class="tabbar-item" href="#"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <path d="M4 11l8-7 8 7v8a1 1 0 0 1-1 1h-4v-6h-6v6H5a1 1 0 0 1-1-1z" /> </svg> <span class="tabbar-label">Home</span> </a> <a class="tabbar-item" href="#" aria-current="page"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <circle cx="11" cy="11" r="6" /> <path d="m20 20-4-4" /> </svg> <span class="tabbar-label">Search</span> </a> <a class="tabbar-item" href="#"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <path d="M5 5h14v14H5zM9 9h6M9 13h6" /> </svg> <span class="tabbar-label">Library</span> </a> <a class="tabbar-item" href="#"> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <circle cx="12" cy="9" r="3.5" /> <path d="M5 20c1-4 4-5 7-5s6 1 7 5" /> </svg> <span class="tabbar-label">Profile</span> </a> </nav></div>#When to use
Use a tab bar for destinations of equal weight that a reader moves between all day. For views of one page use tabs; on a wide screen the same destinations belong in a navbar or a nav. Keep labels to one word: a label that does not fit is cut with an ellipsis before it pushes its neighbors.
#Accessibility
- The bar is a
<nav>with a label, and each item a link witharia-current="page"on the current one. If the items switch panels in place, userole="tablist"withrole="tab"andaria-selected; both states draw the same. - Every item keeps its label. An icon alone is a guess; the word under it is the name.
- Items are at least 56px tall and share the width equally, well over the 44px a touch target needs.
- The bar adds
env(safe-area-inset-bottom)under its items. Setviewport-fit=coverin the viewport meta tag for the inset to apply.
#Classes
| Class | Description |
|---|---|
tabbar | The bar, sticky at the bottom, on a nav with a label: a pane of frosted glass whose items share its width equally |
tabbar-floating | A bar lifted off the edge, with a margin, a surface corner and a floating shadow. With tabbar |
tabbar-item | A destination: an icon over a tabbar-label, on a link or a button |
tabbar-label | The word under the icon, on one line, cut with an ellipsis before it pushes its neighbors |
#Custom properties
| Property | Default | Description |
|---|---|---|
--tabbar-height | 3.5rem | An item's minimum height |
--tabbar-color | var(--color-surface-base) | The color the pane is tinted with |