Why Is My Sticky Header Not Staying on Top?

Sticky header not staying on top problems usually happen when the header is missing a top value, trapped inside the wrong scroll container, placed behind content by z-index, or affected by overflow and stacking context rules.

Sticky Header Fix

Why is my sticky header not staying on top?

A sticky header can work for a few pixels, then disappear. It can stick inside the wrong parent, slide behind a hero section, or stop staying on top when another element creates a new stacking context. The fix is not just “add z-index.” You need to check the sticky offset, parent overflow, scroll container, and stacking order together.

  • position sticky
  • z-index
  • overflow hidden
  • stacking context

What the bug looks like

The header scrolls away, sticks only inside one section, sits behind content, or stops being clickable on mobile.

Why it happens

Sticky behavior depends on the nearest scroll container, the sticky offset, and the stacking context around the header.

What usually fixes it

Put the header high in the HTML, add a real top value, avoid trapping parent overflow, and use a deliberate z-index.

Error 1

position:sticky is missing the sticky offset

position:sticky does not mean “always stay at the top.” It means the element behaves normally until it reaches a specified offset. Without top:0, the browser may have no useful sticky boundary.

Broken code

Missing top value
.site-header {
  position: sticky;
  z-index: 10;
}

Broken visual result

Header scrolls away
not sticking
Brand
Hero section
Content keeps scrolling
The header has sticky positioning, but no clear top point where it should stick.

Correct code

Sticky offset added
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
}

Fixed visual result

Header knows where to stick
Brand
Hero section
Content scrolls under the header
top:0 tells the browser the exact point where the header should become sticky.
Error 2

A parent with overflow is trapping the sticky header

Sticky elements stick relative to their nearest scrolling ancestor. If the header is inside a wrapper with overflow:hidden, overflow:auto, or a short height, the header may only stick inside that wrapper instead of the page.

Broken code

Overflow trap
.page-shell {
  height: 320px;
  overflow: hidden;
}

.site-header {
  position: sticky;
  top: 0;
}

Broken visual result

Sticky is trapped
parent overflow
Brand
Wrapper area
The header cannot stick beyond this parent
The sticky header is not broken. It is obeying the wrong container.

Correct code

Header outside overflow wrapper
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
}

.page-shell {
  overflow: visible;
}

Fixed visual result

Sticky follows the page
Brand
Normal page content
No overflow trap
Keep the sticky header outside unnecessary overflow wrappers when it must stick for the whole page.
Error 3

The header is sticky, but it is behind other content

A header can stay at the top and still look broken if a hero, card, dropdown, or transformed section paints above it. In that case, the issue is stacking order, not sticky behavior.

Broken code

Low z-index
.site-header {
  position: sticky;
  top: 0;
  z-index: 1;
}

.hero-card {
  position: relative;
  z-index: 10;
}

Broken visual result

Content covers header
behind content
Brand
Hero card

This card paints above the sticky header because its z-index wins.

More page content
The sticky header is there, but another layer is visually covering it.

Correct code

Deliberate header layer
.site-header {
  position: sticky;
  top: 0;
  z-index: 1000;
}

.hero-card {
  position: relative;
  z-index: 1;
}

Fixed visual result

Header stays above content
above content
Brand
Hero card

The content keeps its layer, but the header has the higher page-level layer.

More page content
Use a consistent z-index scale for headers, menus, overlays, and content cards.
Error 4

The sticky header is inside the wrong HTML structure

A site-wide sticky header should usually live near the top of the page structure, not inside a hero section, card, slider, or small wrapper. If its parent ends, the sticky behavior ends with it.

Broken code

Header nested too deep
<section class="hero">
  <header class="site-header">...</header>
  <div class="hero-content">...</div>
</section>

<main>...</main>

Broken visual result

Sticky ends with section
wrong parent
Brand
Hero wrapper
Main content after hero
The header cannot stay sticky for the full page if it belongs to a short section.

Correct code

Header at page level
<header class="site-header">...</header>

<main>
  <section class="hero">...</section>
  <section class="content">...</section>
</main>

Fixed visual result

Header controls the page
Brand
Hero section
Content section
A page-level header has a page-level sticky boundary.
Premium pattern

A production-minded sticky header pattern

A reliable sticky header pattern uses a page-level header, a clear sticky offset, a deliberate z-index layer, and avoids placing the header inside wrappers that create scroll or stacking traps.

Premium code

Sticky header system
<header class="site-header">
  <a class="logo" href="/">Brand</a>
  <nav class="main-nav">...</nav>
</header>

<main class="site-main">
  ...
</main>
:root {
  --header-layer: 1000;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--header-layer);
  background: rgba(255,255,255,.96);
  border-bottom: 1px solid #e5e7eb;
}

.site-main {
  min-width: 0;
}

html {
  scroll-padding-top: 80px;
}

Premium visual result

Predictable sticky layer
Brand
Hero section
Content section
Premium sticky headers are not magical. They are page-level elements with clean parents and predictable layers.

Fast practical rule

If a sticky header is not staying on top, do not start by throwing bigger z-index values at it. First confirm top:0, then check parent overflow, then check whether another element created a stacking context above the header.

Debug checklist

  • Check that the header has position:sticky and a real offset like top:0.
  • Inspect every parent of the header for overflow:hidden, overflow:auto, or overflow:scroll.
  • Move the header outside short wrappers, hero sections, sliders, and cards when it should stick for the whole page.
  • Give the header a deliberate page-level z-index, such as z-index:1000.
  • Check whether another element has a higher z-index than the header.
  • Look for stacking context creators like transform, filter, opacity, isolation, or positioned parents.
  • Test mobile breakpoints to make sure the header is not switched back to position:static.
  • If anchor links hide under the header, add scroll-padding-top or scroll-margin-top.
Best first moveAdd or confirm top:0. Sticky needs an offset to know when to stick.
Most common causeA parent wrapper with overflow changes the sticky boundary.
Most misleading causeThe header is sticky, but content paints above it because of z-index or stacking context.
Better mindsetSticky headers need structure, not random z-index numbers.

Final takeaway

A sticky header not staying on top is usually not one single CSS mistake. It is usually a combination of sticky offset, parent overflow, z-index, stacking context, and HTML structure.

Start with top:0, then inspect the parent containers, then fix the stacking order. Once the header is a clean page-level element with a deliberate layer, it becomes predictable on desktop and mobile.

Want more fixes like this?

Browse more CSS, header, and responsive debugging guides in the FrontFixer library.

Leave a Comment