Skip to content

ExpressiveCSS

Browse documentation

Toolbars

Frequently used actions for the current page.

View as Markdown

Use a toolbar for frequently used actions on the current page. There are four toolbars, from two independent choices: a shape (floating or docked) and a color style (standard or vibrant). A toolbar can hold buttons, icon buttons, and text fields, and a floating bar can sit next to a FAB. Don't show a toolbar at the same time as a navigation bar.

Build the bar from a <div class="toolbar">. It is not a <nav> because a toolbar holds commands, and a nav holds destinations. Direct <button> or <a> children are the actions. A <span class="material-symbols" aria-hidden="true"> is the icon. Wrap a label in its own <span>, and give an icon-only action an aria-label. .active marks the selected action. .filled on an action makes it the emphasized control. Toolbars are CSS only, with nothing to AutoInit.

Floating is the default shape and standard is the default color, so neither needs a class. The framework still accepts the floating and standard classes if you want a bar to name both its shape and its color style.

StandardVibrant
Floating class="toolbar" class="toolbar vibrant"
Docked class="toolbar docked" class="toolbar docked vibrant"

Tokens follow the 34.0.21 sets md.comp.toolbar.{standard, vibrant, docked, floating, floating.fab}, behind the M3 toolbar spec. Actions are 48dp targets with a 24dp icon, spaced 4dp apart. At rest they are transparent, with on-surface-variant content.

The framework no longer has the old FAB-to-toolbar transition. Use this toolbar component for persistent command groups.

Floating

Floating is the default shape. The bar sizes to its actions. It is 64dp tall with 32dp stadium corners, elevation 3, and 8dp end insets. When fixed, it sits 16dp from the viewport edge. A floating bar can be horizontal or vertical, can hold many controls, and can sit next to a FAB.

<div class="toolbar">
  <button type="button" aria-label="Stop camera">
    <span class="material-symbols" aria-hidden="true">videocam_off</span>
  </button>
  <button type="button" class="active" aria-label="Hand">
    <span class="material-symbols" aria-hidden="true">back_hand</span>
  </button>
  <button type="button" aria-label="More">
    <span class="material-symbols" aria-hidden="true">more_vert</span>
  </button>
</div>

Wrap a label next to the icon in a <span>. :only-child ignores text nodes, so <span class="material-symbols">edit</span>Edit would look icon-only. Add .filled to an action to make it the emphasized control (16dp corners, primary).

<div class="toolbar">
  <button type="button" aria-label="Undo">
    <span class="material-symbols" aria-hidden="true">undo</span>
  </button>
  <button type="button" class="filled" aria-label="Add">
    <span class="material-symbols" aria-hidden="true">add</span>
  </button>
  <button type="button" aria-label="More">
    <span class="material-symbols" aria-hidden="true">more_vert</span>
  </button>
</div>

Color

Add vibrant to a bar that needs more emphasis. It uses primary-container / on-primary-container, and its selection moves to surface-container / on-surface so it stays visible against the accent. Standard uses surface-container with on-surface-variant content and a secondary-container selection. Either shape takes either color.

The vibrant attribute is a different thing. The toolbar CSS deliberately does not treat it like the class. That attribute is the emphasis foundation, whose one ramp is tertiary. The foundation repaints a bar inside it, or a bar carrying it, without toolbar-specific code. That works because every color above is a token pointed at a --md-sys-color-* role. Selection uses secondary-container, which the foundation leaves alone, so the two do not collide.

<div class="toolbar vibrant">…</div>

Vertical

Add vertical to stack the actions. Only floating bars go vertical. A docked bar stays a horizontal strip.

<div class="toolbar vertical">…</div>

Docked

Add docked to stretch the bar to the full width. A docked bar drops the stadium and the elevation and takes 16dp end insets. Its actions spread from 4dp to 32dp apart as the bar widens. It replaces the bottom app bar and does the same job at 64dp tall instead of 80dp.

Use a docked bar for page actions. Destinations belong on a navigation bar, and the two should not appear together. A child .max is a spacer, not the bar.

This bar has text actions and a spacer:

<div class="toolbar docked">
  <button type="button" aria-label="Download">
    <span class="material-symbols" aria-hidden="true">download</span>
  </button>
  …
</div>

<div class="toolbar docked">
  <button type="button"><span>Back</span></button>
  <span class="max"></span>
  <button type="button" class="filled"><span>Next</span></button>
</div>

Pairing with a FAB

Wrap the toolbar and a sibling .extra.circle FAB in .toolbar-group. The FAB keeps its 56dp size and 16dp corners. It sits 8dp from the bar, at elevation 1 next to the bar's elevation 3. Its color follows the bar's color style, so you mark only the bar. Beside a standard bar it uses secondary-container, and beside a vibrant one it uses tertiary-container. This companion FAB is separate from the in-bar .filled action.

<div class="toolbar-group">
  <div class="toolbar vibrant">…</div>
  <button type="button" class="extra circle" aria-label="Reply">
    <span class="material-symbols" aria-hidden="true">reply</span>
  </button>
</div>

Fixed

Add fixed to pin the bar to the viewport, inset by its own external space. A floating bar sits 16dp from the bottom-center. Add top to move it to the top. A vertical bar sits 24dp from the start edge, and right flips it. A docked bar sticks to the bottom edge, and top sticks it to the top.

<div class="toolbar fixed">…</div>
<div class="toolbar vertical fixed">…</div>
<div class="toolbar docked fixed">…</div>

Tokens

Token Default
--md-comp-toolbar-container-color--md-sys-color-surface-container (primary-container when vibrant)
--md-comp-toolbar-color--md-sys-color-on-surface-variant (on-primary-container when vibrant)
--md-comp-toolbar-container-shape32px (0 when docked)
--md-comp-toolbar-container-height64px
--md-comp-toolbar-leading-space8px (16px when docked)
--md-comp-toolbar-trailing-space8px (16px when docked)
--md-comp-toolbar-between-space4px
--md-comp-toolbar-external-space16px, 24px when vertical (floating only, since a docked bar sits on the edge)
--md-comp-toolbar-min-spacing4px (docked)
--md-comp-toolbar-max-spacing32px (docked)
--md-comp-toolbar-action-size48px
--md-comp-toolbar-icon-size24px
--md-comp-toolbar-selected-container-color--md-sys-color-secondary-container (surface-container when vibrant)
--md-comp-toolbar-selected-color--md-sys-color-on-secondary-container (on-surface when vibrant)
--md-comp-toolbar-floating-fab-between-space8px
--md-comp-toolbar-floating-fab-container-color--md-sys-color-secondary-container (tertiary-container beside a vibrant bar)
--md-comp-toolbar-floating-fab-icon-color--md-sys-color-on-secondary-container (on-tertiary-container beside a vibrant bar)

No matching pages

  • Source color

    The seed every generated ramp derives from. Pick one and browse the docs — the whole theme follows. Error does not: it is a fixed hue.

    Default source: Mist Iris.

    ExpressiveCSS presets: Lagoon, Harbor, Breeze, Cobalt, Iris.

    Bold

    Soft

    Mist

    Glow