Tailwind CSS in Production · Theming and Consistency

The Dropdown Behind the Header

A user menu opened behind the next section no matter how high its z-index went, because a parent created a new stacking context.

Create a free account to save this page, take notes and track your progress. Sign in

Scenario

Example team: a page header uses backdrop-blur for a frosted-glass effect. Inside it, an account dropdown has z-50. Below the header, a hero section has relative z-10.

What you see in production

The dropdown opens behind the hero. Someone changes it to z-[9999]. It still opens behind.

The naive code

<header class="relative backdrop-blur">          <!-- creates a stacking context, z-index auto -> treated as 0 -->
  <div class="absolute z-[9999]">Menu</div>
</header>
<section class="relative z-10">Hero</section>

Reproduce it

Same z-index, different stacking contextsTry it yourself
<div class="grid gap-6 p-6 sm:grid-cols-2">
  <div>
    <div class="relative h-12 rounded-t-lg bg-sky-200/70 p-3 text-sm backdrop-blur">Header (no z-index)
      <div class="absolute top-8 left-3 z-50 w-40 rounded-lg bg-white p-3 shadow-lg ring-1 ring-gray-200">Menu z-50</div>
    </div>
    <div class="relative z-10 h-24 rounded-b-lg bg-rose-300 p-3 text-sm">Hero z-10 covers the menu</div>
  </div>
  <div>
    <div class="relative z-20 h-12 rounded-t-lg bg-sky-200/70 p-3 text-sm backdrop-blur">Header z-20
      <div class="absolute top-8 left-3 z-50 w-40 rounded-lg bg-white p-3 shadow-lg ring-1 ring-gray-200">Menu z-50</div>
    </div>
    <div class="relative z-10 h-24 rounded-b-lg bg-rose-300 p-3 text-sm">Hero z-10 stays below</div>
  </div>
</div>

Root cause

z-index only compares elements within the same stacking context. backdrop-filter, filter, transform, opacity < 1, isolation: isolate and positioned elements with a z-index all create a new one. The menu's z-50 is "50 inside the header", and the header as a whole sits below the hero.

The fix

  • Give the parent that creates the context a z-index above its siblings (z-20 on the header).
  • Render floating UI (menus, dialogs, toasts) in a portal at the end of <body>, or use the native popover attribute / <dialog> which draw in the top layer.
  • Define a small z-index scale in your theme (--z-dropdown, --z-modal) instead of escalating numbers; use isolate deliberately on components.

Trade-offs

  • Portals detach DOM from component structure; handle focus and positioning (Floating UI) carefully.
  • The top layer (popover, <dialog>) needs modern browsers; it's supported in current ones.

Detect it in production

  • Visual tests that open each menu and dialog on pages with blurred or transformed sections.

Key points

  • z-index works within stacking contexts; blur, transforms and opacity create them.
  • Fix the parent's level or move floating UI to a portal or the top layer.

Practice questions

A dropdown with z-50 appears behind a sibling section with z-10. Why?

Answer

The dropdown is inside a parent that creates a stacking context (for example with backdrop-blur, transform or opacity) and that parent sits below the section. z-index only compares elements within the same context; raise the parent or render the dropdown in a portal or the top layer.

Open in the app to mark lessons complete, take notes and track your progress.

Was this page helpful?