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.
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:
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:
: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
setTimeouthacks - 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