Kodokon kodokon.com

Positioning: relative, absolute, fixed, sticky, z-index

Anchor badges, headers, and modals exactly where you want them with CSS positions and a well-managed z-index scale.

8 min · 3 questions

Open this lesson in Kodokon

By default, every element is position: static and follows the document flow. position: relative has two uses: nudging an element slightly without disturbing its neighbors, and above all serving as the reference for children with position: absolute. It's the most common positioning pattern: a promo badge, a tooltip, or an icon anchored to a corner of its parent.

CSS
.product-card {
  position: relative;
}

.promo-badge {
  position: absolute;
  top: 12px;
  right: 12px;
}
The badge anchors to the card's corner, not the page's.

position: fixed pins an element to the viewport, regardless of scrolling: cookie banner, back-to-top button. position: sticky is a hybrid: the element scrolls normally with the page, then locks in place once it reaches the threshold you define (for example top: 0). It's the modern solution for headers that stay visible.

CSS
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: white;
}
Without the top: 0 threshold, sticky has no effect.

When elements overlap, z-index decides which one sits on top - but only for positioned elements. Adopt a documented scale rather than random values: 10 for dropdown menus, 100 for the header, 1000 for modals. Beware: a parent that creates its own stacking context (for example with an opacity below 1) caps the z-index of all its children.

CSS
.dropdown {
  z-index: 10;
}

.site-header {
  z-index: 100;
}

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
}
A clear scale avoids the z-index arms race.

Knowledge check

Make sure you remember the key points of this lesson.

  1. Relative to what does a position: absolute element position itself?
    • Always relative to the browser window
    • Relative to the nearest positioned ancestor, otherwise the viewport
    • Relative to its direct parent, whatever its position
  2. What is the difference between fixed and sticky?
    • fixed always stays pinned to the screen, sticky only locks in place from a scroll threshold onward
    • sticky renders faster than fixed
    • None, they are synonyms
  3. Why can a z-index: 999 have no effect?
    • Because the maximum allowed value is 100
    • Because the element isn't positioned, or is trapped in a lower stacking context
    • Because z-index only works with Grid