Flexbox and grid place elements in the normal flow. Badges on images, dropdown panels, sticky headers and floating action buttons need to leave that flow. Tailwind exposes position, the inset properties and z-index as utilities, and once you know the rules about containing blocks and stacking contexts they become predictable. After this lesson you will be able to overlay content, pin elements to the viewport, and fix the "z-index does nothing" problem for good.
| Class | Positioned relative to | Typical use |
|---|---|---|
| static | Nothing (default) | Reset at a breakpoint |
| relative | Its own normal position | Containing block for absolute children |
| absolute | Nearest positioned ancestor | Badges, overlays, dropdown panels |
| fixed | The viewport | Floating buttons, cookie banners |
| sticky | Its scroll container, within its parent | Headers, table headings, sidebars |
The single most important rule: an absolute element measures its offsets from the nearest ancestor that has relative, absolute, fixed or sticky. Forgetting relative on the parent sends the child to the top of the page.
Offsets are set with top-*, right-*, bottom-*, left-*, the logical start-*/end-*, and the shorthands inset-*, inset-x-*, inset-y-*:
<div class="relative">
<img src="product.jpg" alt="" />
<span class="absolute top-2 left-2 rounded bg-red-600 px-2 text-xs text-white">-20%</span>
<div class="absolute inset-0 bg-black/30"></div>
<div class="absolute inset-x-0 bottom-0 p-4 text-white">Caption</div>
</div>inset-0 stretches an element over its whole containing block, which is how overlays, image fills and click-catching backdrops are built. Negative offsets (-top-2, -right-2) push a badge past the corner. To centre an element exactly, combine offsets with a transform: absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2.
sticky behaves like relative until the element reaches the threshold you set, then pins in place while its parent is still on screen:
<header class="sticky top-0 z-40 bg-white shadow-sm">Site header</header>
<div class="grid grid-cols-[14rem_1fr] gap-8">
<nav class="sticky top-20 self-start">Table of contents</nav>
<article>Long content…</article>
</div>Two conditions are easy to miss. The sticky element needs an offset (top-0), and it can only stick within its parent, so a sidebar must be self-start (not stretched) and its parent must be as tall as the content. Any ancestor with overflow-hidden, overflow-auto or overflow-scroll becomes the scroll container and stops sticking relative to the page; use overflow-clip when you must clip.
Tailwind ships z-0, z-10, z-20, z-30, z-40, z-50, z-auto, negative values such as -z-10, and arbitrary values like z-[100]. The scale is coarse on purpose: a handful of layers is easier to reason about than dozens of magic numbers.
z-index only compares elements inside the same stacking context. A new context is created by a positioned element with a z-index, and also by opacity below 1, transform, filter and isolate. This explains the classic bug where a dropdown with z-50 still appears under a sibling card: its parent has relative z-10, so the dropdown is trapped inside that context.
<!-- isolate creates a context so the -z-10 background stays inside the card -->
<div class="relative isolate rounded-xl bg-white p-6">
<div class="absolute inset-0 -z-10 rounded-xl bg-linear-to-r from-pink-100 to-blue-100"></div>
Content stays above the gradient
</div>Use isolate deliberately on components with internal layers so their z-indexes never leak out and interact with the rest of the page.
relative.sticky header that never sticks because a wrapper has overflow-hidden.z-index ever higher instead of fixing the stacking context with isolate or by moving the element.An element with `absolute top-0 right-0` appears at the top-right of the page instead of its card. What is missing?
absolute offsets are measured from the nearest positioned ancestor, so give the parent relative.inset-0 covers the containing block; combine offsets with -translate-x-1/2 -translate-y-1/2 to centre.sticky needs an offset, a tall enough parent, self-start in flex or grid, and no overflow-hidden ancestor.z-index only competes within one stacking context; transforms, opacity and filters create new ones.isolate on layered components to contain their z-indexes.Next lesson: Responsive Design and Breakpoints — adapt layouts to screen sizes with the mobile-first sm:, md: and lg: prefixes.