Positioning and z-index
static, relative, absolute, fixed, sticky and the stacking context.
Updated
What positioning is
By default, elements sit in the normal flow — one after another, in the order they appear in the HTML. The position property lets you take an element out of the flow or move it relative to something specific.
The position types
| Value | Stays in the flow? | Positioned relative to | When |
|---|---|---|---|
static (default) |
yes | — (top/left have no effect) |
normal |
relative |
yes, the space remains | its own position | a small offset; the reference for absolute children |
absolute |
no | the nearest positioned (non-static) ancestor | a badge on a card, an icon in an input, a dropdown |
fixed |
no | the window (viewport) | modal, overlay, toast, a "back to top" button |
sticky |
yes, until the threshold | the parent's scroll | a stuck header, section titles, a sidebar |
The relative + absolute combo
.card { position: relative; } /* becomes the reference */
.badge { position: absolute; top: 0.5rem; right: 0.5rem; }Without position: relative on the card, the badge would be positioned relative to the first positioned ancestor — often the whole page.
inset
inset: 0 = top: 0; right: 0; bottom: 0; left: 0. A full-screen overlay:
.overlay { position: fixed; inset: 0; background: rgb(0 0 0 / 0.5); }sticky
.site-header { position: sticky; top: 0; }The element flows normally until it reaches top: 0, then it stays stuck — only inside its parent. It doesn't work if an ancestor has overflow: hidden.
z-index and the stacking context
z-index decides who's on top, but only for positioned elements (or flex/grid items). The trap: a new stacking context isolates its children — a child with z-index: 9999 can't rise above an element outside its parent's context.
What creates a stacking context: position + z-index, opacity < 1, transform, filter, isolation: isolate.
The practical rule: keep a small scale (10 header, 20 dropdown, 50 modal), not an arms race with 999999.
Summary
relative= the reference;absolute= relative to the reference;fixed= relative to the screen;sticky= stuck on scroll.inset: 0covers everything.z-indexworks inside the stacking context.