Toolbar
MD3 Expressive toolbar: a container of actions, either docked (a full-width bar — the recommended replacement for the bottom app bar) or floating (an elevated pill, horizontal or vertical), in a standard or vibrant color scheme.
Docked
A 64dp full-width bar with items centered. Place it at the bottom of the screen.
<Toolbar variant="docked" aria-label="Formatting">
<IconButton variant="standard" icon={<BoldIcon />} aria-label="Bold" />
<IconButton variant="standard" icon={<ItalicIcon />} aria-label="Italic" />
</Toolbar>
Floating
A rounded, elevated pill. orientation="vertical" stacks the items (floating
only).
<Toolbar variant="floating" orientation="vertical" aria-label="Zoom">
…
</Toolbar>
Color
color="vibrant" switches to the primary-container scheme for higher
emphasis. Standard IconButtons follow the scheme's content and selected
colors automatically.
<Toolbar variant="floating" color="vibrant" aria-label="Formatting">…</Toolbar>
Expanded / collapsed
On a floating toolbar, startContent / endContent are shown only while
expanded; children always stay. Control it with expanded +
onExpandedChange, or start collapsed with defaultExpanded={false}.
Collapsed content is inert.
const [expanded, setExpanded] = useState(true)
<Toolbar
variant="floating"
aria-label="Edit actions"
expanded={expanded}
onExpandedChange={setExpanded}
startContent={<IconButton variant="standard" icon={<BoldIcon />} aria-label="Bold" />}
endContent={<IconButton variant="standard" icon={<LinkIcon />} aria-label="Link" />}
>
<IconButton variant="filled" icon={<EditIcon />} aria-label="Edit" />
</Toolbar>
Scroll behavior
scrollBehavior observes scrollTarget (default window):
exitAlways— slides the toolbar off the screen edge while scrolling forward and brings it back on scroll back. A docked toolbar becomesposition: sticky; bottom: 0.collapse— a floating toolbar collapses to itschildrenafter 40px of forward scrolling and expands after 40px back, drivingexpanded/onExpandedChange.
Position a floating toolbar yourself (e.g. absolutely, 16dp from the edge). Scroll inside the frames below.
Paragraph 1. Content scrolls behind the toolbar.
Paragraph 2. Content scrolls behind the toolbar.
Paragraph 3. Content scrolls behind the toolbar.
Paragraph 4. Content scrolls behind the toolbar.
Paragraph 5. Content scrolls behind the toolbar.
Paragraph 6. Content scrolls behind the toolbar.
Paragraph 7. Content scrolls behind the toolbar.
Paragraph 8. Content scrolls behind the toolbar.
Paragraph 9. Content scrolls behind the toolbar.
Paragraph 10. Content scrolls behind the toolbar.
Paragraph 11. Content scrolls behind the toolbar.
Paragraph 12. Content scrolls behind the toolbar.
Paragraph 13. Content scrolls behind the toolbar.
Paragraph 14. Content scrolls behind the toolbar.
Paragraph 15. Content scrolls behind the toolbar.
Paragraph 16. Content scrolls behind the toolbar.
Paragraph 17. Content scrolls behind the toolbar.
Paragraph 18. Content scrolls behind the toolbar.
Paragraph 19. Content scrolls behind the toolbar.
Paragraph 20. Content scrolls behind the toolbar.
Paragraph 1. Content scrolls behind the toolbar.
Paragraph 2. Content scrolls behind the toolbar.
Paragraph 3. Content scrolls behind the toolbar.
Paragraph 4. Content scrolls behind the toolbar.
Paragraph 5. Content scrolls behind the toolbar.
Paragraph 6. Content scrolls behind the toolbar.
Paragraph 7. Content scrolls behind the toolbar.
Paragraph 8. Content scrolls behind the toolbar.
Paragraph 9. Content scrolls behind the toolbar.
Paragraph 10. Content scrolls behind the toolbar.
Paragraph 11. Content scrolls behind the toolbar.
Paragraph 12. Content scrolls behind the toolbar.
Paragraph 13. Content scrolls behind the toolbar.
Paragraph 14. Content scrolls behind the toolbar.
Paragraph 15. Content scrolls behind the toolbar.
Paragraph 16. Content scrolls behind the toolbar.
Paragraph 17. Content scrolls behind the toolbar.
Paragraph 18. Content scrolls behind the toolbar.
Paragraph 19. Content scrolls behind the toolbar.
Paragraph 20. Content scrolls behind the toolbar.
const scrollRef = useRef<HTMLDivElement>(null)
<div ref={scrollRef} style={{ height: 480, overflowY: 'auto' }}>
{content}
<Toolbar
variant="docked"
aria-label="Formatting"
scrollBehavior="exitAlways"
scrollTarget={scrollRef}
>
…
</Toolbar>
</div>
The second frame shows the m3 "floating toolbar with FAB" pattern: a floating
toolbar with no children collapses away entirely, and the FAB grows to
size="medium" while it is collapsed. hidden renders the exit state
directly (off-screen and inert).
Accessibility
- Renders
role="toolbar"witharia-orientation. Give each toolbar anaria-label, especially when a page has several. - Keyboard: every item stays in the Tab order, and the arrow keys also move between items — ← / → (mirrored in RTL) for a horizontal toolbar, ↑ / ↓ for a vertical one, Home / End to the ends. Disabled items are skipped and text fields keep their own arrow keys.
- Hidden or collapsed content is
inert. LeavescrollBehaviorunset when every control must stay on screen; motion is instant underprefers-reduced-motion: reduce.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Slots — usually icon buttons, buttons, or text fields. Always shown. |
color | enum | standard | Color scheme. |
defaultExpanded | boolean | true | Initial `expanded` when uncontrolled. |
endContent | ReactNode | — | Floating: items after `children` that are shown only while `expanded` (Compose `trailingContent`). On a docked toolbar they are plain items. |
expanded | boolean | — | Floating: whether `startContent` / `endContent` are shown (controlled). Collapsed content is `inert`. A floating toolbar with no `children` collapses away entirely — pair it with a separate FAB for the m3 "floating toolbar with FAB" pattern (grow the FAB to `size="medium"`, 80dp, while collapsed). |
hidden | boolean | — | State: slides the toolbar off the screen edge (see `scrollBehavior`) and makes it `inert`. Unlike the native `hidden` attribute it keeps its layout box. Overrides `scrollBehavior="exitAlways"`. |
onExpandedChange | ((expanded: boolean) => void) | — | Called when `expanded` should change (e.g. by `scrollBehavior="collapse"`). |
orientation | enum | horizontal | Item flow direction (floating only). |
scrollBehavior | enum | — | Observe `scrollTarget` and hide / collapse the toolbar automatically. A docked toolbar becomes `position: sticky; bottom: 0`; position a floating one yourself (e.g. `position: fixed`, 16dp from the edge). Leave it unset to keep every control on screen — e.g. for assistive-technology users (Compose disables these behaviors while TalkBack is on). Motion is instant under `prefers-reduced-motion: reduce`. |
scrollTarget | ScrollTarget | window | The scroll container observed by `scrollBehavior`. |
startContent | ReactNode | — | Floating: items before `children` that are shown only while `expanded` (Compose `leadingContent`). On a docked toolbar they are plain items. |
variant | enum | docked | Docked (full-width bar) or floating (rounded, elevated). |