Why Is My Fixed Header Covering Content?

Layout Fix

Why is my fixed header covering content even though the layout looks normal?

Why is my fixed header covering content? In most cases, the browser is doing exactly what you asked. A header with position: fixed is removed from the normal document flow, which means the content below it no longer reserves space for it. That is why titles, hero sections, and anchor links often slide underneath the header instead of starting below it.

  • Classic layout bug
  • Usually caused by fixed positioning
  • Often fixed in minutes

What the bug looks like

The page title starts behind the header, the hero looks cut off, or the top of the content seems hidden the moment the page loads.

Why it happens

Fixed elements do not take up normal layout space. The content below them behaves as if the header is not occupying any vertical room.

What usually fixes it

Add an offset equal to the header height, then handle anchor links with scroll-margin-top or use position: sticky when appropriate.

Common broken version

Header overlaps content
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 80px;
}

main {
  /* no top offset */
}

Why this fails

The header is fixed to the viewport, but the main content still starts at the top of the page. Since the header no longer occupies normal layout space, the content slides underneath it.

Simple rule: if a fixed header has height, the content usually needs an offset that matches that height.

Traditional fix

Add top spacing

The most common fix is to add top padding to the content wrapper, main area, or body so the first visible section begins below the fixed header.

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 80px;
}

main {
  padding-top: 80px;
}

A safer version with a custom property

Hard-coding the same height in multiple places works, but it becomes fragile when the header changes later. A custom property makes the relationship easier to maintain.

Better long-term pattern

Single source of truth
:root {
  --header-height: 80px;
}

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--header-height);
}

main {
  padding-top: var(--header-height);
}

The content is hidden, not missing

Developers often think the top section “disappeared,” but it is usually just sitting underneath the fixed header.

The header height may change on mobile

If the header becomes taller on smaller screens, your desktop offset may stop matching the real height.

Shrinking headers need extra care

If the header changes size while scrolling, a static offset may work at load but feel wrong during navigation.

Fast practical rule

If your fixed header is covering content, do not fight the symptom with random margin guesses. Measure the real header height first, then offset the content intentionally.

Why anchor links still break

Many developers fix the top of the page, then click a navigation anchor and discover that the target heading still lands behind the fixed header.

This happens because the browser scrolls the target to the top edge of the viewport, where the fixed header is still covering it.

Modern anchor fix

Use scroll-margin-top
section,
h2,
h3 {
  scroll-margin-top: 96px;
}

Alternative at the scroll container level

Use scroll-padding-top
html {
  scroll-padding-top: 96px;
}

When to use this

scroll-padding-top is useful when the document itself is the scroll container and you want a global offset for anchor navigation.

scroll-margin-top is often more targeted. scroll-padding-top is broader. Both can be excellent depending on the layout.

Sticky vs fixed: which one do you actually need?

Many people use position: fixed by default, then spend time fixing overlap bugs that would not exist with position: sticky.

A sticky header stays in the normal flow until it reaches its sticking point. That means the document still reserves space for it, which often avoids the classic “content hidden behind the header” problem.

Sticky alternative

Often simpler
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
}

Use fixed when the header must stay pinned

Fixed works well when the header must remain attached to the viewport at all times and you are prepared to manage the offset intentionally.

Use sticky when flow matters

Sticky is often better when you want the header to participate in normal layout before sticking, especially for simpler document-style pages.

Do not treat them as interchangeable

They can feel similar visually, but they behave very differently in layout. Choosing the wrong one creates unnecessary bugs.

Debug checklist

  • Measure the real header height instead of guessing it.
  • Check whether the header height changes between desktop and mobile.
  • Confirm the content wrapper, main, or first section has a matching top offset.
  • Test in-page anchor links to see whether section headings still land behind the header.
  • Use scroll-margin-top or scroll-padding-top for anchor navigation.
  • Ask whether position: sticky would solve the UX need more cleanly than position: fixed.
Best first move Inspect the header height and apply a deliberate content offset before changing anything else.
Most overlooked issue Anchor links can still break even after the top of the page looks fixed.
Most common wrong instinct Blaming z-index when the real issue is simply that the header left document flow.
Better mindset Fixed headers are not broken by default. They just require layout compensation because the browser no longer reserves space for them.

Final takeaway

Why is my fixed header covering content? Because a fixed header is removed from normal flow, and the content below it is not automatically pushed down. The browser is not making a mistake. It is following the layout model exactly.

Add an intentional top offset, protect anchor links with scroll-margin-top or scroll-padding-top, and consider position: sticky if you do not actually need a fully fixed header. Once you understand that, this bug becomes much easier to solve and much easier to avoid.

Want more fixes like this?

Browse more responsive and layout debugging guides or jump to the full FrontFixer library.

Leave a Comment