← Component Library
Layout Component

The Header

The bar across the top of almost every site — logo, navigation, and a call to action. Here's how to build one that's clean, sticky, responsive, and accessible.

01 · Anatomy

What goes in a header

A header orients visitors and stays consistent across every page. Most headers hold three things, left to right.

Brand / logo

Usually top-left, and almost always a link back to the home page.

Primary navigation

The main links to your top-level pages, wrapped in a <nav>.

Action

A call-to-action button, search, or sign-in — the one thing you most want visitors to do.

Use the real tags. Wrap it in <header> and put the links in <nav> so screen readers announce it as a banner and a navigation landmark.
02 · Build It

A basic header with Flexbox

One flex row does the heavy lifting: justify-content: space-between pushes the logo to the left and the nav to the right.

Logo left, nav + CTA right — one flex row.

HTML

<header class="site-header">
  <a class="logo" href="index.html">Brandr</a>
  <nav class="nav">
    <a href="#">Home</a>
    <a href="#">Features</a>
    <a href="#">Pricing</a>
    <a href="#">About</a>
    <a class="cta" href="#">Sign up</a>
  </nav>
</header>

CSS

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;  /* logo left, nav right */
  padding: 14px 20px;
}
.nav { display: flex; gap: 22px; align-items: center; }
.nav a { text-decoration: none; }
03 · Sticky

Keep it in view while scrolling

A sticky header stays pinned to the top as the page scrolls — handy for navigation on long pages. Scroll inside the box below to see it stick.

Scroll this box — the header above stays put.

More content…

…and more content…

…and even more so it scrolls.

HTML

<header class="site-header">
  <a class="logo" href="index.html">Brandr</a>
  <nav class="nav">
    <a href="#">Home</a>
    <a href="#">Docs</a>
    <a class="cta" href="#">Get started</a>
  </nav>
</header>

CSS

.site-header {
  position: sticky;
  top: 0;          /* pin to the top edge */
  z-index: 10;     /* sit above page content */
  background: #fff; /* opaque so content doesn't show through */
}
Always set a background. Without it, page content scrolls visibly behind a sticky header. A subtle shadow on scroll also helps it stand out.
04 · Responsive

Collapse to a menu on small screens

A row of links won't fit on a phone. The common pattern: hide the nav and show a hamburger button below a breakpoint, then toggle the menu open with a little JavaScript.

Phone view: links hide, a labeled hamburger button appears.

HTML

<header class="site-header">
  <a class="logo" href="index.html">Brandr</a>
  <nav class="nav"><a href="#">Home</a><a href="#">Docs</a></nav>
  <button class="burger" aria-label="Open menu">&#9776;</button>
</header>

CSS

.burger { display: none; }            /* hidden on desktop */

@media (max-width: 640px) {
  .nav { display: none; }             /* hide inline links */
  .burger { display: inline-flex; }   /* show the menu button */
}
For the full open/close menu with JavaScript, see the Mobile Navigation page.
05 · Best Practices

Make it solid & accessible

06 · Copy & Paste

The complete, ready-to-use header

Everything above in one working piece — sticky and responsive, with no outside libraries. Copy each block into the matching spot on your page: the CSS into your stylesheet (or a <style> in the <head>), the HTML right after your opening <body> tag, and the JavaScript just before your closing </body> tag.

1. CSS — paste into your stylesheet

<style>
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between; /* logo left, nav right */
  padding: 14px 24px;
  background: #fff;               /* opaque: content can't show through */
  border-bottom: 1px solid #e9edf3;
  position: sticky;               /* stays pinned while scrolling */
  top: 0;
  z-index: 100;                   /* sits above page content */
}
.site-header .logo { font-weight: 800; font-size: 1.15rem; color: #111; text-decoration: none; }
.site-header .nav  { display: flex; gap: 24px; align-items: center; }
.site-header .nav a { color: #4b5563; text-decoration: none; font-size: .95rem; }
.site-header .nav a:hover { color: #111; }
.site-header .cta  { background: #2563eb; color: #fff; padding: 9px 16px; border-radius: 8px; font-weight: 600; text-decoration: none; }
.site-header .burger { display: none; font-size: 1.6rem; line-height: 1; background: none; border: none; color: #111; cursor: pointer; }

@media (max-width: 640px) {
  .site-header .nav {
    display: none;                /* hidden until the button opens it */
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: flex-start; gap: 4px;
    padding: 12px 24px 18px; background: #fff;
    border-bottom: 1px solid #e9edf3;
  }
  .site-header .nav.open { display: flex; } /* JS adds .open */
  .site-header .burger  { display: inline-flex; }
}
</style>

2. HTML — paste at the top of your <body>

<header class="site-header">
  <a class="logo" href="index.html">Brandr</a>
  <button class="burger" aria-label="Open menu" aria-expanded="false">&#9776;</button>
  <nav class="nav" aria-label="Main">
    <a href="#">Home</a>
    <a href="#">Features</a>
    <a href="#">Pricing</a>
    <a href="#">About</a>
    <a class="cta" href="#">Sign up</a>
  </nav>
</header>

3. JavaScript — paste before </body>

<script>
  const burger = document.querySelector('.site-header .burger');
  const nav    = document.querySelector('.site-header .nav');
  burger.addEventListener('click', () => {
    const open = nav.classList.toggle('open');
    burger.setAttribute('aria-expanded', open);
    burger.setAttribute('aria-label', open ? 'Close menu' : 'Open menu');
  });
</script>
That's the whole component. Keep the .site-header class names as-is (rename in all three blocks if they clash with your page), and put the <header> directly inside <body>.
07 · Full Page

The whole thing as one file

Everything above — structure, styles, and the menu script — combined into one complete HTML file. Copy it into a new file called index.html, open it in a browser, and it just works — no libraries, no build step. Here's the live result, then the full code.

Live preview

Complete HTML — copy this whole file

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Site</title>
  <style>
    * { box-sizing: border-box; margin: 0; padding: 0; }
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; color: #1f2433; }

    /* ===== Header ===== */
    .site-header {
      display: flex; align-items: center; justify-content: space-between;
      padding: 14px 24px; background: #fff; border-bottom: 1px solid #e9edf3;
      position: sticky; top: 0; z-index: 100;   /* sticky + above content */
    }
    .site-header .logo { font-weight: 800; font-size: 1.15rem; color: #111; text-decoration: none; }
    .site-header .nav { display: flex; gap: 24px; align-items: center; }
    .site-header .nav a { color: #4b5563; text-decoration: none; font-size: .95rem; }
    .site-header .nav a:hover { color: #111; }
    .site-header .cta { background: #2563eb; color: #fff; padding: 9px 16px; border-radius: 8px; font-weight: 600; text-decoration: none; }
    .site-header .burger { display: none; font-size: 1.6rem; line-height: 1; background: none; border: none; color: #111; cursor: pointer; }

    main { padding: 28px 24px; }
    .page { max-width: 760px; margin: 0 auto; }
    .page h1 { font-size: 2rem; margin-bottom: 12px; }
    .page p { color: #4b5563; margin-bottom: 14px; }

    /* ===== Mobile: collapse links into the menu button ===== */
    @media (max-width: 640px) {
      .site-header .nav {
        display: none; position: absolute; top: 100%; left: 0; right: 0;
        flex-direction: column; align-items: flex-start; gap: 4px;
        padding: 12px 24px 18px; background: #fff; border-bottom: 1px solid #e9edf3;
      }
      .site-header .nav.open { display: flex; }   /* JS toggles .open */
      .site-header .burger { display: inline-flex; }
    }
  </style>
</head>
<body>

  <header class="site-header">
    <a class="logo" href="index.html">Brandr</a>
    <button class="burger" aria-label="Open menu" aria-expanded="false">&#9776;</button>
    <nav class="nav" aria-label="Main">
      <a href="#">Home</a>
      <a href="#">Features</a>
      <a href="#">Pricing</a>
      <a href="#">About</a>
      <a class="cta" href="#">Sign up</a>
    </nav>
  </header>

  <main>
    <section class="page">
      <h1>Welcome to my site</h1>
      <p>This is your page content. Scroll down — the sticky header stays pinned to the top of the window.</p>
      <p>Make the window narrow and the links collapse into the &#9776; menu button.</p>
      <p style="height: 700px;">Plenty of room to scroll…</p>
    </section>
  </main>

  <script>
    const burger = document.querySelector('.site-header .burger');
    const nav = document.querySelector('.site-header .nav');
    burger.addEventListener('click', () => {
      const open = nav.classList.toggle('open');
      burger.setAttribute('aria-expanded', open);
      burger.setAttribute('aria-label', open ? 'Close menu' : 'Open menu');
    });
  </script>
</body>
</html>
That's a real, standalone page. The live preview above is rendered from the exact code in the box — so what you copy is precisely what you see.
08 · Related

Keep building

Pair the header with a Footer, style the links in Navigation, make it collapse with Mobile Navigation, or browse everything in the Component Library.