📘 Lesson  ·  Lesson 29

z-index and Stacking

z-index और Stacking

What z-index Is

Web pages have depth — when elements overlap, one appears in FRONT of the other. z-index controls this stacking order: which element sits on top and which goes behind. Think of it as the elements' distance toward you (the "z" axis, coming out of the screen). A higher z-index means "closer to the viewer, on top." This is essential for anything that overlaps: dropdown menus, popups, modals, tooltips, and sticky headers that must appear above the content they cover.

Why It Needs position — the #1 gotcha

.box {
    z-index: 999;        /* this does NOTHING on its own! */
}

.box {
    position: relative;  /* z-index needs a position (not static) */
    z-index: 999;        /* NOW it works */
}
The single most common z-index bug: z-index is IGNORED on elements with the default position: static. It only works when the element has position set to relative, absolute, fixed, or sticky. So if you set z-index: 9999 and nothing changes, the fix is almost always to add position: relative. This trips up nearly everyone the first time — "why won't my z-index work?" — and the answer is nearly always a missing position. Remember: no position, no z-index.

The Stacking Order — higher wins

.behind  { position: absolute; z-index: 1; }   /* lower = further back */
.middle  { position: absolute; z-index: 5; }
.front   { position: absolute; z-index: 10; }  /* higher = on top */
┌─────────┐ ┌─┤ front │ (z-index: 10, on top) ┌─┤ │ (z: 5) │ │ │ └─────────┘ │ └───────────┘ └─ behind (z-index: 1, furthest back)

The rule is simple: higher z-index appears on top. An element with z-index: 10 covers one with z-index: 5. Values can be any number (even negative, to push behind). When two elements have the same z-index (or none), the one that comes LATER in the HTML wins — later elements naturally stack on top of earlier ones. You don't need huge numbers; small values like 1, 2, 10 are usually plenty, though people often use 9999 for "always on top" elements.

Stacking Context — the confusing part

<div style="position: relative; z-index: 1">      <!-- parent A -->
    <div style="position: relative; z-index: 9999">Child</div>
</div>
<div style="position: relative; z-index: 2">Parent B</div>

/* Parent B (z:2) appears ABOVE the child (z:9999)!
   because the child's 9999 only competes INSIDE parent A */
The advanced gotcha that confuses even experienced developers: z-index values only compete WITHIN the same "stacking context." When a positioned parent has a z-index, it creates a new stacking context, and its children's z-index values only matter relative to each OTHER inside that parent — not against elements outside it. So a child with z-index: 9999 inside a parent with z-index: 1 can still sit BELOW a sibling of the parent with z-index: 2. If a huge z-index mysteriously won't go on top, a parent's stacking context is usually why. Advanced, but knowing it exists saves hours of confusion.

Real-World Uses

  • Modals/popups: a high z-index (plus a full-screen overlay) makes a dialog appear above everything.
  • Dropdown menus: z-index ensures the open menu covers the content below it, not vice versa.
  • Sticky/fixed headers: a header needs z-index to stay above page content as it scrolls past.
  • Tooltips and badges: small z-index bumps to sit above their surroundings.
  • Layered graphics: stacking images or decorative shapes deliberately.
A practical tip: keep z-index values organised and small. Instead of random 9999s everywhere (which leads to "z-index wars" where you keep adding higher numbers), use a simple scale — e.g. dropdowns 100, sticky header 200, modals 300. This keeps layering predictable. z-index chaos is a real maintenance headache; a little discipline prevents it.

Exam Corner

Q: What does z-index control? The stacking order — which overlapping element appears on top.

Q: Why might z-index not work? The element has position: static (default); z-index needs position relative/absolute/fixed/sticky.

Q: Higher or lower z-index appears on top? Higher.

Q: What happens with equal z-index values? The element later in the HTML appears on top.

Q: Why might a z-index: 9999 child still be behind another element? Its parent's stacking context — z-index only competes within the same context.

z-index क्या करता है

.box1 { position: relative; z-index: 1; }
.box2 { position: relative; z-index: 2; }   /* box1 ke OOPER */
z-index control करता है कौन-सा element दूसरे के ऊपर दिखे जब वे overlap करें. Screen को कागज़ों का ढेर समझिए: x-axis बाएं-दाएं है, y-axis ऊपर-नीचे, और z-axis आपकी ओर बाहर आता है. ज़्यादा z-index मतलब element आपके नज़दीक है, तो वह कम z-index वाले elements को ढक देता है. यह dropdowns, modals, tooltips, और fixed headers के लिए ज़रूरी है — कोई भी चीज़ जो बाकी content के ऊपर तैरनी चाहिए.

बड़ा gotcha — position चाहिए

/* ✗ Kaam NAHI karta — position static (default) hai */
.box { z-index: 999; }

/* ✓ Chalta hai — koi bhi non-static position */
.box { position: relative; z-index: 999; }
.box { position: absolute; z-index: 999; }
.box { position: fixed;    z-index: 999; }
यह #1 कारण है कि z-index "काम नहीं करता": यह सिर्फ POSITIONED elements पर लगता है. अगर element का position default static है, z-index पूरी तरह ignore होता है — चाहे आप 999999 लिखें. हल सरल है: position: relative (या absolute/fixed/sticky) जोड़िए. position: relative बिना offsets के element को हिलाता नहीं, तो यह z-index चालू करने का सुरक्षित तरीका है. जब भी z-index नज़रअंदाज़ हो रहा लगे, पहले position जांचिए.

z-index Values

z-index: auto;    /* default — parent ke saath stack karta */
z-index: 0;
z-index: 1;
z-index: 100;
z-index: -1;      /* content ke PEECHE bhejta hai */
Values कोई भी पूर्णांक हो सकती हैं. ज़्यादा value वाला element कम value वाले के ऊपर दिखता है. Negative values element को अपने parent के background के पीछे भी भेज सकती हैं — decorative shapes के लिए काम का. आम practice: बड़े jumps (10, 100, 1000) use कीजिए ताकि बाद में बीच में कुछ डालने की जगह रहे. z-index: 9999 जैसी बेतुकी values से बचिए; वे बताती हैं कि stacking योजना बिगड़ चुकी है.

Stacking Context — सूक्ष्म जाल

.parent { position: relative; z-index: 1; }
.child  { position: relative; z-index: 999; }   /* parent ke andar KAID */

.other  { position: relative; z-index: 2; }     /* .child ke OOPER dikhega! */
जब कोई positioned element z-index पाता है, वह अपने बच्चों के लिए नया "stacking context" बनाता है. उस context के अंदर, बच्चों के z-index सिर्फ आपस में तुलना होते हैं — वे बाहर नहीं निकल सकते. तो ऊपर, .child का z-index: 999 उसे .other (z-index 2) के ऊपर नहीं लाता, क्योंकि उसका parent सिर्फ z-index 1 पर है. पूरा parent 1 पर बैठता है, और उसके अंदर सब कुछ उसी के साथ जाता है. जब "ऊंचा z-index काम नहीं कर रहा" तब यही आमतौर पर कारण है — parent की जांच कीजिए.

व्यावहारिक इस्तेमाल

/* Fixed header sabse ooper rahe */
.header { position: fixed; top: 0; z-index: 100; }

/* Dropdown page content ke ooper */
.dropdown { position: absolute; z-index: 50; }

/* Modal overlay — sabse ooper */
.overlay { position: fixed; inset: 0; z-index: 1000; }
.modal   { position: fixed; z-index: 1001; }
असली project में एक सरल z-index "पैमाना" बनाइए और उस पर टिकिए: content 1-10, dropdowns 50, sticky header 100, modals 1000+. यह छोटी योजना बाद की उलझन बचाती है, और अगर आप CSS variables use करें (--z-modal: 1000) तो पूरी परत-व्यवस्था एक जगह से दिखती और बदलती है — design tokens का एक और अच्छा उदाहरण.

Exam Corner

Q: z-index क्या control करता है? Overlap करते elements का stacking order (कौन ऊपर दिखे).

Q: z-index का मुख्य gotcha क्या है? यह सिर्फ positioned elements पर काम करता है (position: static पर नहीं).

Q: z-index चालू करने का सुरक्षित तरीका? position: relative जोड़िए — यह element को हिलाता नहीं.

Q: Negative z-index क्या करता है? Element को content के पीछे भेजता है.

Q: Stacking context क्या है? Positioned + z-index वाला element अपने बच्चों के लिए नया context बनाता है, जिसके बाहर वे नहीं निकल सकते.
← Back to CSS Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

इस पेज का code यहाँ तैयार है — बदलिए और तुरंत नतीजा देखिए. कुछ install किए बिना.
👁 Live Preview
सब कुछ आपके browser में ही चलता है — कोई server, कोई signup नहीं. JavaScript का console.log देखने के लिए F12 दबाइए.