# Site header

Starts every page of a site with its name, its main links and a few controls, in one row that stays at the top.

### Known issues
The header's own issues are those of the pieces of core it is made of.

- **The menu panel.** If you keep pressing Tab after the last link of the open menu, focus moves on into the page and the menu stays open over it; Escape closes it. Without CSS anchor positioning the panel and the language list open at the height of a one-row header from the top of the window, so with enlarged text they can cover part of the header. See the [navbar's known issues](https://nandovejer.github.io/luz/docs/catalog/navbar/#known-issues).
- **Sticky header and enlarged text.** The scroll padding of `.o-sticky` is a minimum: at 300% text, with the header wrapped to several rows, Safari can leave a field reached with Tab under it. Set `scroll-padding-block-start` on `html` to your header's real height, or leave out `.o-sticky`.

### Copy the markup
Header markup
```html
<header class="luz-site-header o-sticky">
  <div class="o-container o-container--inline o-row">
    <button class="luz-nav-toggle" type="button" popovertarget="site-nav" aria-label="Menu">
      <svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6h16M4 12h16M4 18h16"/></g></svg>
    </button>
    <a class="luz-site-header__brand" href="/">Acme Summit</a>
    <nav class="luz-navbar" id="site-nav" aria-label="Main" popover>
      <ul class="luz-navbar__list">
        <li><a class="luz-navbar__link" href="/programme/" aria-current="page">Programme</a></li>
        <li><a class="luz-navbar__link" href="/speakers/">Speakers</a></li>
        <li><a class="luz-navbar__link" href="/tickets/">Tickets</a></li>
      </ul>
    </nav>
    <div class="o-row luz-site-header__actions">
      <a class="luz-btn luz-btn--ghost" href="/account/">Log in</a>
    </div>
  </div>
</header>
```

A blog or a newspaper adds the modifier, and catalog's search and language switch go in the actions:

Publication header markup
```html
<header class="luz-site-header luz-site-header--publication o-sticky">
  <div class="o-container o-container--inline o-row">
    <button class="luz-nav-toggle" type="button" popovertarget="site-nav" aria-label="Sections">
      <svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6h16M4 12h16M4 18h16"/></g></svg>
    </button>
    <a class="luz-site-header__brand" href="/">The Vejer Review</a>
    <nav class="luz-navbar" id="site-nav" aria-label="Sections" popover>
      <ul class="luz-navbar__list">
        <li><a class="luz-navbar__link" href="/news/" aria-current="true">News</a></li>
        <li><a class="luz-navbar__link" href="/culture/">Culture</a></li>
        <li><a class="luz-navbar__link" href="/opinion/">Opinion</a></li>
      </ul>
    </nav>
    <div class="o-row luz-site-header__actions">
      <luz-search>…</luz-search>
      <luz-lang-switch>…</luz-lang-switch>
    </div>
  </div>
</header>
```

### Variants and options
One modifier. The header is a class of catalog on a native `<header>`, laid out by core's objects in the markup.

- `.luz-site-header`: On `<header>`: the page surface, a rule underneath, the gaps of its row, and the anchor its panels open under
- `.luz-site-header--publication`: For a blog or a newspaper: the brand is the publication's name, in the heading font, larger, and underlined on hover; at 768 px and below it fills the room between the menu button and the actions and wraps there
- `.luz-site-header__brand`: The site's name as a link to the home page: semibold, not underlined, at least 44 px tall; it takes the free room of the row. A logo `<img>` inside it is 44 px tall
- `.luz-site-header__actions`: On a `.o-row` at the end of the row: a search, a [language switch](https://nandovejer.github.io/luz/docs/catalog/lang-switch/), a button
- `.o-sticky` (core): Keeps the header at the top while the page scrolls, in a window at least 30 rem tall; see [the page and its bars](https://nandovejer.github.io/luz/docs/components/layout/#objects-page)
- `.o-container.o-container--inline.o-row` (core): The row: the width and gutters of the page, wrapping rather than overflowing
- `.luz-nav-toggle`, `.luz-navbar` (catalog): The menu button and the links: see the [navbar](https://nandovejer.github.io/luz/docs/catalog/navbar/)

### How it works
CSS from `components/site-header.css` of `@luz-ds/catalog` on core's objects and the catalog's navbar. No JavaScript.

- The header adds the skin only: the page surface, the rule underneath, the brand, and the gaps of the row (8 px between rows, 16 px between items, 24 px from 769 px). Core gives the rest: `.o-sticky` the stickiness and the scroll padding, `.o-container--inline` the gutters, `.o-row` the wrapping row, and the navbar the links and their panel.
- A one-row header is core's `--luz-bar-h` tall: 44 px controls, 4 px above and below, and the 1 px rule. With enlarged text the row wraps and the header grows.
- The header names itself the anchor `--luz-bar`, scoped to itself. Where the browser supports CSS anchor positioning, the navbar's panel and the list of the catalog's `<luz-lang-switch>` open under it on one row or on two. Elsewhere they open at `--luz-bar-h` from the top of the window.
- With the modifier the brand is the publication's name: `--luz-font-heading` at `--luz-text-xl`, `--luz-text-lg` at 640 px and below.
- Without `@luz-ds/catalog` nothing changes: its rules that refine the catalog's elements match nothing.

### Without JavaScript
Nothing changes: the menu is a popover opened by the button's `popovertarget`, with no script, and the links are plain links.

### Keyboard and ARIA
- **Order:** the menu button, the brand, the links, then the actions, in the order of the source. With the menu open, the next Tab after the button goes into the panel's links.
- **Keys:** Enter or Space on the button opens and closes the panel; Escape closes it and returns focus to the button.
- **Names:** the `<nav>` has an `aria-label` ("Main"). The button's name is "Menu"; the browser exposes its expanded state. The current link has `aria-current="page"` and an underline.
- **Brand:** a link, never a heading: the page's one `h1` is its own title. A logo is an `<img>` whose `alt` is the name, with no text beside it.
- **Landmarks:** a `<header>` that is a direct child of `<body>` is the banner. Put the [skip link](https://nandovejer.github.io/luz/docs/components/skip-link/) before it.

### When to use
Use the header at the top of every page of a landing site, a blog or a newspaper: the visitor sees which site this is and reaches its main parts from any page.

- The plain header for a landing site, a product or an event.
- With `--publication` for a blog or a newspaper; for the front page of a newspaper, where the name and the date set the tone, use the [masthead](https://nandovejer.github.io/luz/docs/catalog/masthead/).

### When not to use
Do not use it in an app: the [app bar](https://nandovejer.github.io/luz/docs/catalog/app-bar/) is the bar of the main area beside the sidebar.

- One header per page, never inside a component: it is the page's banner.
- A single page that fits one screen needs a heading and a skip link, not a header.
