Navigation

v0.0.4
Marketing blocks

Header

A site header: the brand, the links, the actions and a drawer for narrow screens.

A site header holds the brand, the main links and the one thing you most want a visitor to do. This block is a navbar with everything a real site adds to it: a menu under one of the links, a second action that steps aside when the room is short, and a drawer that takes over on a phone. None of it needs a script.

Header

<a class="skip" href="#header-main">Skip to content</a><header class="navbar">  <a class="navbar-brand" 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="M12 3a9 9 0 1 0 0 18a9 9 0 0 0 0-18M12 3a9 9 0 0 0 0 18" />    </svg>Atlas</a>  <nav class="navbar-nav" aria-label="Main">    <button type="button" class="navbar-link" popovertarget="header-product">Product      <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="m6 9 6 6 6-6" />      </svg>    </button>    <div class="popover p(4)" id="header-product" popover>      <ul class="list list-interactive w(320)">        <li>          <a class="list-row" href="#">            <span class="list-media">              <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 14c0-5 4-10 11-10 0 7-5 11-10 11zM5 14l-2 1 1 3M10 19l-1 2-3-1M14.5 9.5h.01" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Deployments</p>              <p class="list-description">Every push gets its own address.</p>            </div>          </a>        </li>        <li>          <a class="list-row" href="#">            <span class="list-media">              <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="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Domains</p>              <p class="list-description">Certificates that renew themselves.</p>            </div>          </a>        </li>        <li>          <a class="list-row" href="#">            <span class="list-media">              <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 19h16M7 16V9M12 16V5M17 16v-4" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Analytics</p>              <p class="list-description">Traffic and speed, without cookies.</p>            </div>          </a>        </li>        <li>          <a class="list-row" href="#">            <span class="list-media">              <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="M12 3l8 3v6c0 4.5-3.2 8-8 9-4.8-1-8-4.5-8-9V6z" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Firewall</p>              <p class="list-description">Rules at the edge, in every region.</p>            </div>          </a>        </li>      </ul>    </div>    <a class="navbar-link" href="#">Pricing</a>    <a class="navbar-link" href="#">Docs</a>    <a class="navbar-link" href="#">Changelog</a>  </nav>  <div class="navbar-end">    <a class="btn btn-quiet btn-sm hidden inline-flex@container(--xl)" href="#">Sign in</a>    <a class="btn btn-primary btn-sm" href="#">Start deploying</a>    <button type="button" class="btn btn-quiet btn-square btn-sm navbar-toggle" commandfor="header-menu" command="show-modal" aria-label="Open the menu">      <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 8h16M4 16h16" />      </svg>    </button>  </div>  <dialog class="dialog dialog-drawer" id="header-menu" closedby="any" aria-label="Menu" style="--dialog-width: 20rem">    <div class="dialog-body flex flex-col gap-md">      <nav class="nav" aria-label="Main, in the menu">        <div class="nav-label">Product</div>        <a class="nav-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 14c0-5 4-10 11-10 0 7-5 11-10 11zM5 14l-2 1 1 3M10 19l-1 2-3-1M14.5 9.5h.01" />          </svg>Deployments</a>        <a class="nav-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="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" />          </svg>Domains</a>        <a class="nav-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 19h16M7 16V9M12 16V5M17 16v-4" />          </svg>Analytics</a>        <a class="nav-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="M12 3l8 3v6c0 4.5-3.2 8-8 9-4.8-1-8-4.5-8-9V6z" />          </svg>Firewall</a>        <div class="nav-label">Company</div>        <a class="nav-item" href="#">Pricing</a>        <a class="nav-item" href="#">Docs</a>        <a class="nav-item" href="#">Changelog</a>      </nav>    </div>    <footer class="dialog-footer">      <a class="btn" href="#">Sign in</a>      <a class="btn btn-primary" href="#">Start deploying</a>    </footer>    <button type="button" class="btn btn-quiet btn-square btn-sm dialog-close" commandfor="header-menu" command="close" aria-label="Close the menu">      <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="M6 6l12 12M18 6 6 18" />      </svg>    </button>  </dialog></header><main class="max-w(720) mx-auto px-lg py-3xl flex flex-col gap-md" id="header-main" tabindex="-1">  <h1 class="heading heading-2xl">The page under the header</h1>  <p class="lead">Scroll, and the bar takes its material. Open Product for the menu; choose Phone for the drawer.</p>  <div class="sheet p-xl h(240)"></div>  <div class="sheet p-xl h(240)"></div>  <div class="sheet p-xl h(240)"></div></main>
Scroll the page, open Product, then choose Phone and open the menu.

Blocks are markup to copy. They take the page's own text color and size; the previews set fg-text-body text-sm on the body. Each block is a size container, so it reflows by its own width.

#What is in it

  • The bar is a navbar. It sticks, and takes its frosted material only once content is under it.
  • A link that opens a menu is a button. navbar-link is on links and on one <button popovertarget>: Product opens something, the others go somewhere.
  • The product menu is a popover holding a list. It anchors to its button and flips at the edge of the viewport. Each row is a link with a title and one sentence.
  • Two actions, one of which steps aside. Both are buttons on links. "Sign in" is hidden inline-flex@container(--xl): it shows from 36rem of bar. "Start deploying" is the one btn-primary, and it always stays.
  • The toggle exists only while the links are hidden. navbar-toggle shows below 36rem of bar; that threshold belongs to the navbar.
  • The drawer is a dialog holding a nav. commandfor opens it; its close button, a click outside or Esc closes it. It holds the same links as the bar, and both actions in its footer.

The bar is the size container here, so @container(…) utilities inside it measure the bar.

#With an announcement

A banner sits above the header and scrolls away with the page, while the bar sticks. Make it a <dialog open> with banner-dismissible to let a visitor close it.

With an announcement

<a class="skip" href="#header-main-b">Skip to content</a><div class="banner banner-inverse" role="region" aria-label="Announcement">  <p class="banner-content">    <span class="banner-title">Atlas 4 is here.</span>Faster builds and a new dashboard.    <a class="banner-action" href="#">Read the notes</a>  </p></div><header class="navbar">  <a class="navbar-brand" 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="M12 3a9 9 0 1 0 0 18a9 9 0 0 0 0-18M12 3a9 9 0 0 0 0 18" />    </svg>Atlas</a>  <nav class="navbar-nav" aria-label="Main">    <button type="button" class="navbar-link" popovertarget="header-product-b">Product      <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="m6 9 6 6 6-6" />      </svg>    </button>    <div class="popover p(4)" id="header-product-b" popover>      <ul class="list list-interactive w(320)">        <li>          <a class="list-row" href="#">            <span class="list-media">              <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 14c0-5 4-10 11-10 0 7-5 11-10 11zM5 14l-2 1 1 3M10 19l-1 2-3-1M14.5 9.5h.01" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Deployments</p>              <p class="list-description">Every push gets its own address.</p>            </div>          </a>        </li>        <li>          <a class="list-row" href="#">            <span class="list-media">              <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="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Domains</p>              <p class="list-description">Certificates that renew themselves.</p>            </div>          </a>        </li>        <li>          <a class="list-row" href="#">            <span class="list-media">              <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 19h16M7 16V9M12 16V5M17 16v-4" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Analytics</p>              <p class="list-description">Traffic and speed, without cookies.</p>            </div>          </a>        </li>        <li>          <a class="list-row" href="#">            <span class="list-media">              <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="M12 3l8 3v6c0 4.5-3.2 8-8 9-4.8-1-8-4.5-8-9V6z" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Firewall</p>              <p class="list-description">Rules at the edge, in every region.</p>            </div>          </a>        </li>      </ul>    </div>    <a class="navbar-link" href="#">Pricing</a>    <a class="navbar-link" href="#">Docs</a>    <a class="navbar-link" href="#">Changelog</a>  </nav>  <div class="navbar-end">    <a class="btn btn-quiet btn-sm hidden inline-flex@container(--xl)" href="#">Sign in</a>    <a class="btn btn-primary btn-sm" href="#">Start deploying</a>    <button type="button" class="btn btn-quiet btn-square btn-sm navbar-toggle" commandfor="header-menu-b" command="show-modal" aria-label="Open the menu">      <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 8h16M4 16h16" />      </svg>    </button>  </div>  <dialog class="dialog dialog-drawer" id="header-menu-b" closedby="any" aria-label="Menu" style="--dialog-width: 20rem">    <div class="dialog-body flex flex-col gap-md">      <nav class="nav" aria-label="Main, in the menu">        <div class="nav-label">Product</div>        <a class="nav-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 14c0-5 4-10 11-10 0 7-5 11-10 11zM5 14l-2 1 1 3M10 19l-1 2-3-1M14.5 9.5h.01" />          </svg>Deployments</a>        <a class="nav-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="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" />          </svg>Domains</a>        <a class="nav-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 19h16M7 16V9M12 16V5M17 16v-4" />          </svg>Analytics</a>        <a class="nav-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="M12 3l8 3v6c0 4.5-3.2 8-8 9-4.8-1-8-4.5-8-9V6z" />          </svg>Firewall</a>        <div class="nav-label">Company</div>        <a class="nav-item" href="#">Pricing</a>        <a class="nav-item" href="#">Docs</a>        <a class="nav-item" href="#">Changelog</a>      </nav>    </div>    <footer class="dialog-footer">      <a class="btn" href="#">Sign in</a>      <a class="btn btn-primary" href="#">Start deploying</a>    </footer>    <button type="button" class="btn btn-quiet btn-square btn-sm dialog-close" commandfor="header-menu-b" command="close" aria-label="Close the menu">      <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="M6 6l12 12M18 6 6 18" />      </svg>    </button>  </dialog></header><main class="max-w(720) mx-auto px-lg py-3xl flex flex-col gap-md" id="header-main-b" tabindex="-1">  <h1 class="heading heading-2xl">An announcement over the header</h1>  <p class="lead">The banner scrolls away with the page; the bar stays.</p>  <div class="sheet p-xl h(240)"></div>  <div class="sheet p-xl h(240)"></div>  <div class="sheet p-xl h(240)"></div></main>

#Floating

navbar-floating gives the bar a margin, a surface's corner and its material from the start. max-w(960) mx-auto keeps it from stretching across a wide screen.

Floating

<a class="skip" href="#header-main-f">Skip to content</a><header class="navbar navbar-floating max-w(960) mx-auto">  <a class="navbar-brand ml-xs" 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="M12 3a9 9 0 1 0 0 18a9 9 0 0 0 0-18M12 3a9 9 0 0 0 0 18" />    </svg>Atlas</a>  <nav class="navbar-nav" aria-label="Main">    <button type="button" class="navbar-link" popovertarget="header-product-f">Product      <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="m6 9 6 6 6-6" />      </svg>    </button>    <div class="popover p(4)" id="header-product-f" popover>      <ul class="list list-interactive w(320)">        <li>          <a class="list-row" href="#">            <span class="list-media">              <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 14c0-5 4-10 11-10 0 7-5 11-10 11zM5 14l-2 1 1 3M10 19l-1 2-3-1M14.5 9.5h.01" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Deployments</p>              <p class="list-description">Every push gets its own address.</p>            </div>          </a>        </li>        <li>          <a class="list-row" href="#">            <span class="list-media">              <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="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Domains</p>              <p class="list-description">Certificates that renew themselves.</p>            </div>          </a>        </li>        <li>          <a class="list-row" href="#">            <span class="list-media">              <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 19h16M7 16V9M12 16V5M17 16v-4" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Analytics</p>              <p class="list-description">Traffic and speed, without cookies.</p>            </div>          </a>        </li>        <li>          <a class="list-row" href="#">            <span class="list-media">              <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="M12 3l8 3v6c0 4.5-3.2 8-8 9-4.8-1-8-4.5-8-9V6z" />              </svg>            </span>            <div class="list-body">              <p class="list-title">Firewall</p>              <p class="list-description">Rules at the edge, in every region.</p>            </div>          </a>        </li>      </ul>    </div>    <a class="navbar-link" href="#">Pricing</a>    <a class="navbar-link" href="#">Docs</a>    <a class="navbar-link" href="#">Changelog</a>  </nav>  <div class="navbar-end">    <a class="btn btn-quiet btn-sm hidden inline-flex@container(--xl)" href="#">Sign in</a>    <a class="btn btn-primary btn-sm" href="#">Start deploying</a>    <button type="button" class="btn btn-quiet btn-square btn-sm navbar-toggle" commandfor="header-menu-f" command="show-modal" aria-label="Open the menu">      <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 8h16M4 16h16" />      </svg>    </button>  </div>  <dialog class="dialog dialog-drawer" id="header-menu-f" closedby="any" aria-label="Menu" style="--dialog-width: 20rem">    <div class="dialog-body flex flex-col gap-md">      <nav class="nav" aria-label="Main, in the menu">        <div class="nav-label">Product</div>        <a class="nav-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 14c0-5 4-10 11-10 0 7-5 11-10 11zM5 14l-2 1 1 3M10 19l-1 2-3-1M14.5 9.5h.01" />          </svg>Deployments</a>        <a class="nav-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="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" />          </svg>Domains</a>        <a class="nav-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 19h16M7 16V9M12 16V5M17 16v-4" />          </svg>Analytics</a>        <a class="nav-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="M12 3l8 3v6c0 4.5-3.2 8-8 9-4.8-1-8-4.5-8-9V6z" />          </svg>Firewall</a>        <div class="nav-label">Company</div>        <a class="nav-item" href="#">Pricing</a>        <a class="nav-item" href="#">Docs</a>        <a class="nav-item" href="#">Changelog</a>      </nav>    </div>    <footer class="dialog-footer">      <a class="btn" href="#">Sign in</a>      <a class="btn btn-primary" href="#">Start deploying</a>    </footer>    <button type="button" class="btn btn-quiet btn-square btn-sm dialog-close" commandfor="header-menu-f" command="close" aria-label="Close the menu">      <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="M6 6l12 12M18 6 6 18" />      </svg>    </button>  </dialog></header><main class="max-w(720) mx-auto px-lg py-3xl flex flex-col gap-md" id="header-main-f" tabindex="-1">  <h1 class="heading heading-2xl">A header that floats</h1>  <p class="lead">It keeps a margin from the edges and its material from the start.</p>  <div class="sheet p-xl h(240)"></div>  <div class="sheet p-xl h(240)"></div>  <div class="sheet p-xl h(240)"></div></main>

#Accessibility

  • The first element of the page is a skip link to <main>, which has tabindex="-1" so focus moves with the jump. The header is what it skips.
  • The header is a <header>; its links are in a <nav> with a label. The drawer holds a second <nav> with a different label.
  • The product link is a button: it opens something instead of going somewhere. The popover it opens is a list of links, reachable with Tab and closed with Escape.
  • Mark the current page with aria-current="page" on its link, in the bar and in the drawer.
  • Set scroll-padding-top: 3.5rem on the root, so a link to a heading does not land under the bar.