Skip to content

ExpressiveCSS

Browse documentation

Navbar

Material Design 3 top app bars, from the HTML.

View as Markdown

Build a top app bar from plain elements, a <header> whose child is a <nav>. The heading is the headline. Icon-only links and buttons are the leading and trailing actions. A <menu> (or <ul>) holds text destinations. There is no navbar, nav-wrapper, or brand-logo class. To switch between app views at the bottom of the screen, use a navigation bar.

Tokens follow the M3 app bar spec. The container is surface at rest. The headline is on-surface at title-large. Icons are 24dp in a 48dp target, inset 4dp, and inherit the header color, so a fill and on-* pair stays readable. The small bar is 64dp tall. Pair a fill utility with its on-* text class if you want a colored bar.

Top app bars stay pinned to the top by default, without a helper class. The layout is CSS. AppBar collapses header.medium and header.large on scroll. It also opens the related search view when the user selects a search field in the bar. Navigation rails and tabs are separate components. Do not nest either one in the header.

Small

The small bar is the default. It has a leading icon, a headline, and trailing actions. DOM order sets the layout. The headline grows, so anything after it sits on the end.

<header>
  <nav aria-label="Main">
    <button type="button" aria-label="Menu">
      <span class="material-symbols" aria-hidden="true">menu</span>
    </button>
    <h2>Title</h2>
    <button type="button" aria-label="Search"><span class="material-symbols" aria-hidden="true">search</span></button>
    <button type="button" aria-label="More"><span class="material-symbols" aria-hidden="true">more_vert</span></button>
  </nav>
</header>

Destinations

Put text links in a <menu>. Place the menu after the heading to align it on the end, or first to align it on the start. When the bar has to collapse, hide the menu below the Expanded breakpoint and use a full-screen navigation dialog or modal expanded rail.

<header>
  <nav aria-label="Main">
    <h2>Title</h2>
    <menu>
      <li><a href="/sass">Sass</a></li>
      <li><a href="/components">Components</a></li>
      <li><a class="active" href="/javascript">JavaScript</a></li>
    </menu>
  </nav>
</header>

Put active on the link, not the list item. The state layer mixes currentColor at 8% hover and 10% active, so it follows the theme and any fill you put on the header.

Center-aligned

Add center to the header. This takes the headline out of flow, so the leading and trailing actions can sit on the edges without shifting it. Keep the title short enough that it does not run under the icons.

<header class="center">
  <nav aria-label="Main">
    <button type="button" aria-label="Back">
      <span class="material-symbols" aria-hidden="true">arrow_back</span>
    </button>
    <h2>Title</h2>
    <button type="button" aria-label="More"><span class="material-symbols" aria-hidden="true">more_vert</span></button>
  </nav>
</header>

Medium and large flexible

These use the same markup as the small bar. Add medium for the Expressive medium-flexible bar, 112dp with a headline-medium title on the second row. Add large for large-flexible, 120dp with display-small. The deprecated medium and large bars used headline-small at 152dp. Do not recreate those.

The title wraps to two lines. The order property moves it onto the bottom row, so the first row can hold the leading icon on the start and the trailing icons on the end. Add center as well to center that second-row title. On scroll, AppBar adds collapsed and the bar becomes the small 64dp row.

<header class="medium">
  <nav aria-label="Main">
    <button type="button" aria-label="Back">
      <span class="material-symbols" aria-hidden="true">arrow_back</span>
    </button>
    <h2>Medium title</h2>
    <button type="button" aria-label="More"><span class="material-symbols" aria-hidden="true">more_vert</span></button>
  </nav>
</header>

<header class="large">…</header>

Subtitle

For a subtitle, wrap the heading and a <p> in an <hgroup>. That is the HTML for a heading plus a subheading. There is no subtitle class. Small uses label-medium. Medium-flexible grows to 136dp and uses label-large. Large-flexible grows to 152dp and uses title-medium.

<header class="medium">
  <nav aria-label="Main">
    <button type="button" aria-label="Back">
      <span class="material-symbols" aria-hidden="true">arrow_back</span>
    </button>
    <hgroup>
      <h2>Medium title</h2>
      <p>Subtitle</p>
    </hgroup>
    <button type="button" aria-label="More"><span class="material-symbols" aria-hidden="true">more_vert</span></button>
  </nav>
</header>

Fixed

Every top app bar stays pinned with position: sticky and top: 0. You need no helper class or wrapper. At rest the bar is surface, the same as the page. Once content scrolls under it, supporting browsers fill it with surface-container through animation-timeline: scroll(), so it stands apart from the body. M3 Expressive uses this fill instead of a shadow. In browsers without that API, the bar keeps its resting color.

The documentation header on this site is a fixed small bar. A second fixed bar on this page would sit on top of it, so the live example is the site header itself.

<header>
  <nav aria-label="Main">
    <h2>Title</h2>
    <button type="button" aria-label="Search"><span class="material-symbols" aria-hidden="true">search</span></button>
  </nav>
</header>

Color

Put primary on-primary-text, or any fill and on-* pair, on the header. The default fill is surface, and color utilities win over it because they live in the utilities layer. Icons inherit the header color. Set --md-comp-top-app-bar-trailing-icon-color to var(--md-sys-color-on-surface-variant) if you want the spec's muted trailing icons.

<header class="primary on-primary-text">
  <nav aria-label="Main">
    <h2>Primary</h2>
  </nav>
</header>

Component tokens you can set on the header (or on :root):

Token Default
--md-comp-top-app-bar-container-color--md-sys-color-surface
--md-comp-top-app-bar-scrolled-container-color--md-sys-color-surface-container
--md-comp-top-app-bar-headline-color--md-sys-color-on-surface
--md-comp-top-app-bar-leading-icon-colorinherit (spec: on-surface)
--md-comp-top-app-bar-trailing-icon-colorinherit (spec: on-surface-variant)
--md-comp-top-app-bar-container-height64px
--md-comp-top-app-bar-leading-icon-size24px

Search

For a search app bar, put a <search class="search-bar"> in the nav in place of the headline. Icons beside it sit outside the search, and icons inside it stay on the search bar. The input is centered. Focusing or clicking the field opens a docked .search-view.

A full-screen <dialog> view takes over the page, so it opens on a click, Enter or the Down arrow instead of on focus. Tabbing through the bar does not open it, and focus coming back after it closes does not reopen it. Query text and application-managed focus are preserved.

Search results are provided by your application.

<header>
  <nav aria-label="Main">
    <button type="button" aria-label="Menu">
      <span class="material-symbols" aria-hidden="true">menu</span>
    </button>
    <search class="search-bar" aria-label="Search">
      <span class="material-symbols" aria-hidden="true">search</span>
      <input type="search" placeholder="Search" aria-label="Search" aria-controls="search-results">
    </search>
  </nav>
</header>
<dialog id="search-results" class="search-view full-screen" aria-label="Search">
  <form method="dialog">
    <input type="search" aria-label="Search query">
    <button type="submit">Close search</button>
  </form>
</dialog>

A <form> in the nav still fills the space between the leading action and anything after it. The input sits unstyled in the bar and needs no extra field class. Its text uses the complete body-large type role, including letter-spacing, and follows overrides of that role's type tokens.

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