CSS Positioning (static to sticky)

Difficulty: Beginner

Question

Explain the different CSS position values. How does z-index work?

Answer

CSS position values:

1. static (default): normal document flow, top/left/z-index ignored 2. relative: stays in flow, offset from its normal position 3. absolute: removed from flow, positioned relative to nearest positioned ancestor 4. fixed: removed from flow, positioned relative to viewport 5. sticky: hybrid - relative until scroll threshold, then fixed

Z-index only works on positioned elements (not static). It creates stacking contexts.

Code examples

Position Values Compared

/* static: default, ignores top/left */
.static { position: static; }

/* relative: offset from normal position */
.relative {
  position: relative;
  top: 10px;   /* pushed down 10px */
  left: 20px;  /* pushed right 20px */
  /* Original space is preserved */
}

/* absolute: relative to positioned parent */
.parent {
  position: relative; /* creates positioning context */
}
.absolute {
  position: absolute;
  top: 0;
  right: 0;
  /* Removed from flow, top-right of .parent */
}

/* fixed: relative to viewport */
.fixed-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  /* Stays at top when scrolling */
}

/* sticky: relative until scroll point */
.sticky-nav {
  position: sticky;
  top: 0; /* becomes fixed at top: 0 */
}

Absolute needs a positioned ancestor (relative is most common). Without one, it positions relative to the document body.

Z-Index and Stacking Context

/* z-index only works on positioned elements */
.behind {
  position: relative;
  z-index: 1;
}
.in-front {
  position: relative;
  z-index: 10;
}

/* Stacking context: z-index is LOCAL */
.parent-a {
  position: relative;
  z-index: 1;
}
.parent-a .child {
  position: relative;
  z-index: 9999; /* still behind parent-b! */
}
.parent-b {
  position: relative;
  z-index: 2; /* parent-b is above parent-a */
}

/* What creates a stacking context: */
/* - position + z-index (not auto) */
/* - opacity < 1 */
/* - transform, filter, perspective */
/* - isolation: isolate */

Z-index is scoped to stacking contexts. A child can never appear above an element that is above its parent's stacking context.

Practical: Modal Overlay

/* Modal overlay pattern */
.overlay {
  position: fixed;
  inset: 0; /* shorthand for top/right/bottom/left: 0 */
  background: rgb(0 0 0 / 0.5);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal {
  position: relative;
  background: white;
  padding: 2rem;
  border-radius: 0.5rem;
  max-width: 500px;
  width: 90%;
}

/* Close button in top-right */
.modal .close-btn {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
}

Fixed positioning with inset: 0 creates a full-screen overlay. The modal inside uses relative positioning to be the anchor for the absolute close button.

Key points

Concepts covered

Position, Static, Relative, Absolute, Fixed, Sticky, Z-Index