CSS Z-index
The Position lesson placed boxes. z-index answers the next question: when two boxes overlap, which one sits closer to the reader? Think of paper sheets on a desk — higher sheets cover lower ones. Learn the everyday rules before inventing huge numbers.
A z-index toolkit
📊 Z-index at a glance
| Idea | Everyday job |
|---|---|
z-index |
Sets paint order among overlapping siblings in the same stacking context |
| Positioned first | Usually needs position other than static (or certain modern layout children) |
| Higher wins | Larger integers paint later — they appear on top |
auto |
Default — follow document order and parent context rules |
| Stacking context | A “cage” — children compare among themselves, not with the whole page |
| Calm scale | Prefer small steps (1, 2, 10) and named roles over 9999 races |
z-index does not move a box left or right. It only changes who covers whom when boxes already share the same screen space.
Raise a badge above its card
Give the card a positioned home, then lift the badge with a modest z-index. Sibling order alone can work, but an explicit layer makes intent readable.
.card {
position: relative;
}
.card__badge {
position: absolute;
top: 0.5rem;
right: 0.5rem;
z-index: 2;
padding: 0.2rem 0.45rem;
background: #0b5fff;
color: #fff;
}
Overlay above the page
Modals and drawers usually sit above ordinary content. Pair a positioned overlay with a clear layer number — and keep page content lower on purpose.
.page {
position: relative;
z-index: 1;
}
.modal {
position: fixed;
inset: 0;
z-index: 10;
background: rgba(0, 0, 0, 0.45);
}
Compare siblings, not the whole world
Among siblings in one context, the higher z-index wins. When values tie, later DOM siblings typically paint on top. Start comparisons inside one parent before chasing page-wide wars.
.stack {
position: relative;
}
.stack .card-a {
position: absolute;
z-index: 1;
}
.stack .card-b {
position: absolute;
z-index: 2;
}
Stacking contexts cage children
A parent with its own stacking context (for example positioned + z-index) can trap children. A child with z-index: 999 cannot jump above a sibling outside that parent if the parent itself sits lower. Fix the parent layer — do not only inflate the child.
.panel {
position: relative;
z-index: 1;
}
.panel .popup {
position: absolute;
z-index: 999;
}
.toast {
position: fixed;
z-index: 5;
}
A calm z-index habit
Name roles (--layer-badge, --layer-modal) or use a tiny scale. Avoid 99999 unless you are debugging. Remember: placement is position; layering is z-index; float clearing waits for the next lessons.
:root {
--layer-base: 1;
--layer-badge: 2;
--layer-modal: 10;
}
.badge {
position: absolute;
z-index: var(--layer-badge);
}
.modal {
position: fixed;
z-index: var(--layer-modal);
}
Try it yourself
- Place an absolute badge on a relative card and set
z-index: 2. - Build a fixed backdrop/modal with
z-index: 10above page content at1. - Give two overlapping absolute siblings different z-index values and swap them.
- Nest a high z-index child inside a low z-index parent — watch the cage.
- Rewrite one “9999” into a named custom property scale.
Common mistakes
- Expecting
z-indexon a plainstaticbox to reorder everything - Fighting stacking contexts by only raising the nested child
- Racing with
99999instead of a readable scale - Treating this lesson like Position (placement) or Display (box type)
- Using z-index to invent page columns instead of layout tools
Summary
z-indexcontrols who paints on top when boxes overlap- It usually needs a non-static position (or special layout cases)
- Higher values win inside the same stacking context
- Parent contexts can cage children — fix the right level
- Prefer small named scales; leave float for upcoming lessons
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 Instructions
- Read each question carefully
- Select the best answer for each question
- You can retake the quiz as many times as you want
- Your progress will be shown at the top