Skip to content

Tailwind Z-Index Utilities

Z-index utilities determine which positioned elements appear on top when they overlap. This lesson explains Tailwind's z-index scale, stacking contexts, and practical layering patterns for modals and dropdowns.

What Is Z-Index in Tailwind?

The z-* utilities map to the CSS z-index property, which only has an effect on elements with a position value other than static (relative, absolute, fixed, or sticky).

Higher z-index values sit on top of lower ones within the same stacking context. Tailwind provides a default scale, plus arbitrary value support for one-off cases.

<div class="relative">
  <div class="absolute inset-0 z-0 bg-slate-200"></div>
  <div class="absolute inset-0 z-10 flex items-center justify-center text-white">
    On top
  </div>
</div>

The z-10 layer renders above the z-0 layer because both share the same relative parent's stacking context.

Z-Index Utility Syntax

class="z-0 | z-10 | z-20 | z-30 | z-40 | z-50 | z-auto"
  • Z-index only affects positioned elements (relative, absolute, fixed, sticky).
  • Higher numbers stack above lower numbers within the same stacking context.
  • z-auto resets to the default stacking behavior, letting document order decide.
  • Arbitrary values like z-[100] escape the default scale when needed.

Z-Index Cheatsheet

Tailwind's default z-index scale and common layering conventions.

Class Value Typical Use
z-0 0 Base layer content
z-10 10 Slightly raised elements, cards on hover
z-20 20 Dropdown menus
z-30 30 Sticky headers/navbars
z-40 40 Fixed overlays or side panels
z-50 50 Modals and top-level dialogs
z-auto auto Resets to default stacking behavior
z-[100] 100 (arbitrary) Escape hatch above the default scale

Understanding Stacking Contexts

Z-index values only compare within the same stacking context. A z-50 element inside a parent with a lower stacking context can still render behind a z-10 element from a completely different stacking context, because contexts don't automatically inherit from siblings.

New stacking contexts are created by properties like position combined with z-index, opacity less than 1, transform, and filter. Being aware of this prevents confusing "my modal is behind everything even though it has z-50" bugs.

Layering a Modal Above Everything

A common convention is to reserve the highest z-index values for modals and toast notifications, since they must appear above navigation bars, dropdowns, and every other layered element on the page.

<nav class="sticky top-0 z-30 bg-white shadow">...</nav>

<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
  <div class="rounded-lg bg-white p-6">Modal content</div>
</div>

The modal's z-50 guarantees it renders above the sticky nav's z-30.

Keeping a Consistent Z-Index Scale

Rather than picking random z-index values per component, define a small, documented scale for your project (for example: 10 for cards, 20 for dropdowns, 30 for sticky nav, 40 for overlays, 50 for modals) so new components don't accidentally clash.

Layer Suggested Value Example Elements
Base UI z-0 / z-10 Cards, raised panels
Navigation z-20 / z-30 Dropdowns, sticky navbar
Overlays z-40 Side drawers, toasts
Modals z-50 Dialogs, confirmation modals

Common Mistakes

  • Applying a z-* utility to an element that is still position: static, which has no effect at all.
  • Assuming a higher z-index always wins, without accounting for separate stacking contexts created by ancestors.
  • Using arbitrarily huge values like z-[9999] everywhere instead of maintaining a small, consistent scale.
  • Forgetting that opacity less than 1 or a transform on an ancestor creates a new stacking context that can trap children below unrelated elements.
  • Not testing overlapping UI (dropdowns opened while a sticky header is visible) before shipping.

Key Takeaways

  • Z-index utilities only affect elements with a non-static position value.
  • Higher z-index values stack above lower ones within the same stacking context.
  • New stacking contexts can be created by transforms, opacity, and filters, not just z-index.
  • Standardizing a z-index scale per project prevents overlapping UI conflicts.
  • Reserve the highest values in your scale for modals and toast notifications.

Pro Tip

If increasing z-index doesn't fix a stacking issue, the real problem is usually a stacking context created by an ancestor, check for transforms, opacity, or filters higher up the DOM tree.