</> ConvertAtlas Developer Tools
Level 2 · Intermediate — Layout & Responsive Lesson 21 Intermediate 14 min

Positioning and Z-Index

Static, relative, absolute, fixed and sticky — plus how stacking contexts and z-index really work.

Positioning lets you take elements out of the normal flow and place them precisely — badges on cards, sticky headers, modals, tooltips. It is powerful but trips up beginners, so let us make it clear.

The five position values

ValueBehaviour
staticDefault — normal flow, ignores top/left
relativeNormal flow, but can be nudged with offsets
absoluteRemoved from flow, positioned to nearest positioned ancestor
fixedRemoved from flow, positioned to the viewport
stickyNormal until scrolled to a threshold, then sticks

Relative + absolute: the key combo

The most common pattern: set a parent to <code>position: relative</code>, then a child to <code>position: absolute</code>. The child is now positioned relative to that parent — perfect for badges, overlays and tooltips.

HTML
<div class="card"><span class="badge">New</span>Product card</div>
CSS
.card{position:relative;background:#e0f2fe;padding:28px;border-radius:12px}
.badge{position:absolute;top:10px;right:10px;background:#ef4444;color:#fff;padding:3px 9px;border-radius:999px;font-size:.75rem}
Result
The badge sits relative to its positioned parent.

Sticky positioning

<code>position: sticky</code> is a hybrid: an element behaves normally until you scroll to a threshold (like <code>top: 0</code>), then it sticks in place. It is the modern way to make sticky headers and section labels — no JavaScript needed.

css
.header {
  position: sticky;
  top: 0;
}

Z-index and stacking contexts

When positioned elements overlap, <code>z-index</code> decides what is on top — higher wins. But there is a catch: z-index only compares elements within the same stacking context. A parent with its own z-index (or opacity, transform, etc.) creates a new context, trapping its children's z-index inside it. This is the source of most "my z-index does nothing" bugs.

Common mistake
Don't
.modal { z-index: 99999; }
Do
/* ensure the modal is not trapped
   inside a low-z-index parent context */
.modal { position: fixed; z-index: 100; }

Setting a huge z-index like 9999 to force something on top, when the real problem is a parent stacking context. Fix the context, do not escalate numbers.

Best practice

Use position: sticky for headers, relative+absolute for overlays, and keep z-index values small and organised (e.g. 10, 20, 100). If z-index seems broken, look for a parent that created a stacking context.

Try it yourself

Build a card with position: relative and add an absolutely-positioned "Sale" badge in the top-right corner. Then make a header position: sticky; top: 0 and scroll a tall page to see it stick.

Quick quiz

1. absolute positions relative to…

2. Which value sticks after scrolling to a threshold?

3. z-index only compares elements…

4. fixed positions relative to…

Key takeaways
  • Five positions: static, relative, absolute, fixed, sticky.
  • relative parent + absolute child positions overlays and badges.
  • position: sticky makes headers stick with no JavaScript.
  • z-index only works within a stacking context — fix the context, not the number.