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.
<header> and put the links in <nav> so screen readers announce it as a banner and a navigation landmark.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; }
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.
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 */
}
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">☰</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 */
}
Make it solid & accessible
- Wrap it in
<header>and use a<nav aria-label="Main">for the links. - The logo should link to
index.html(home). - The hamburger button needs a real
aria-label(e.g., “Open menu”) — never an icon alone. - Keep it keyboard-reachable: every link and button should be tab-focusable with a visible focus ring.
- Ensure text/background contrast meets 4.5:1, including on a sticky/transparent header.
- Mark the current page (e.g.,
aria-current="page") so people know where they are.
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">☰</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>
.site-header class names as-is (rename in all three blocks if they clash with your page), and put the <header> directly inside <body>.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">☰</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 ☰ 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>
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.