How to stop a sticky header from covering your headings

How to stop a sticky header from covering your headings

Ship reliable AI agents, not just demos

Move beyond chatbot wrappers. Build durable AI agents and long-running workflows in TypeScript that fit your existing stack, no reinvented backend.

Explore Trigger.dev

You click a link in a table of contents. The page jumps to the section, but the heading is hidden underneath your sticky header. The user lands mid-paragraph and has to scroll back up to see where they are.

Every site with a fixed header and anchor links has this bug, and most fix it with JavaScript scroll math or ugly invisible padding hacks.

The fix

One CSS property on the targets:

css
h2, h3 {
  scroll-margin-top: 80px;
}

That’s it. scroll-margin-top tells the browser: when scrolling this element into view, leave this much space above it. The heading now lands just below your 80px header, exactly where the eye expects it.

It works for every way an element gets scrolled into view: anchor links, element.scrollIntoView(), even keyboard focus navigation.

Make it track your header automatically

Hardcoding 80px breaks the day your header changes height. Store the height once and reference it everywhere:

css
:root {
  --header-height: 80px;
}

header {
  height: var(--header-height);
}

h2, h3, [id] {
  scroll-margin-top: calc(var(--header-height) + 1rem);
}

The + 1rem adds a little breathing room so the heading doesn’t touch the header edge.

Where this comes up constantly

  • Documentation sites: tables of contents are wall-to-wall anchor links
  • Blog posts: “jump to section” links and heading anchors shared in URLs
  • FAQ pages: linking straight to one question
  • Skip links: a “skip to content” link that lands under the header defeats its purpose

Why it matters

  • Zero JavaScript: replaces scroll-offset calculations and setTimeout hacks
  • Works everywhere scrolling happens: anchor links, scrollIntoView, keyboard focus
  • Accessible by default: keyboard users tabbing through content get the same offset

Click any anchor link on your site right now. If the heading lands under your header, add one line of scroll-margin-top and ship it.

Happy coding!
Marko

Rate this issue

Your ratings shape which issues I recommend to you.