🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
REFERENCEcss

css Documentation

LOADING ENGINE...

Z-index

AI & DATA SCIENCE // z-index

The z-index property sets the stacking order of a positioned element along the depth axis, determining which overlapping elements appear in front of, or behind, others.

Syntax

z-index: auto | integer;

Deep Dive Course

z-index only has an effect on an element that's positioned, meaning it has a position value other than static — a higher z-index value places an element in front of overlapping elements with a lower value, or the default auto, within the same stacking context. Crucially, z-index values are only compared directly between elements sharing the same stacking context, and certain CSS properties, like giving an element a transform, opacity below 1, or a value other than none for filter, create a brand-new, isolated stacking context for that element and its descendants, meaning a very high z-index inside one stacking context still can't beat even a low z-index belonging to a completely separate, sibling stacking context positioned in front of it.

1Understanding Z-index

z-index only has an effect on an element that's positioned, meaning it has a position value other than static — a higher z-index value places an element in front of overlapping elements with a lower value, or the default auto, within the same stacking context. Crucially, z-index values are only compared directly between elements sharing the same stacking context, and certain CSS properties, like giving an element a transform, opacity below 1, or a value other than none for filter, create a brand-new, isolated stacking context for that element and its descendants, meaning a very high z-index inside one stacking context still can't beat even a low z-index belonging to a completely separate, sibling stacking context positioned in front of it.

💡

A surprisingly high z-index value that still fails to bring an element to the front is often caused by that element being trapped inside a separate stacking context, created by a property like transform or opacity on one of its ancestors — z-index values are only meaningfully compared within the same stacking context, not globally across the whole page.

editor.html
.modal {
  position: fixed;
  z-index: 1000;
}

.overlay {
  position: fixed;
  z-index: 999;
}
localhost:3000

2Practical Example

Here is a real-world application of Z-index showing how it is used in production CSS code.

editor.html
.parent {
  transform: scale(1);
}

.child {
  position: relative;
  z-index: 9999;
}

.sibling-of-parent {
  position: relative;
  z-index: 1;
}
localhost:3000

3Best Practices

Follow these guidelines when working with Z-index:

1. Only apply z-index to elements that already have a non-static position value, since it has no effect otherwise

2. Investigate whether an ancestor is unintentionally creating a new stacking context, via properties like transform, opacity, or filter, when a high z-index still doesn't bring an element to the front

3. Keep z-index values organized and intentional, rather than an ever-escalating series of arbitrarily large numbers, to keep the actual stacking logic understandable

⚠️

Tip: A surprisingly high z-index value that still fails to bring an element to the front is often caused by that element being trapped inside a separate stacking context, created by a property like transform or opacity on one of its ancestors — z-index values are only meaningfully compared within the same stacking context, not globally across the whole page.

editor.html
.modal {
  position: fixed;
  z-index: 1000;
}

.overlay {
  position: fixed;
  z-index: 999;
}
localhost:3000

Examples

Example 01Basic Usage
.modal {
  position: fixed;
  z-index: 1000;
}

.overlay {
  position: fixed;
  z-index: 999;
}
Example 02Advanced Example
.parent {
  transform: scale(1);
}

.child {
  position: relative;
  z-index: 9999;
}

.sibling-of-parent {
  position: relative;
  z-index: 1;
}

Best Practices

  • Only apply z-index to elements that already have a non-static position value, since it has no effect otherwise
  • Investigate whether an ancestor is unintentionally creating a new stacking context, via properties like transform, opacity, or filter, when a high z-index still doesn't bring an element to the front
  • Keep z-index values organized and intentional, rather than an ever-escalating series of arbitrarily large numbers, to keep the actual stacking logic understandable

Interview Question

Why can an element with z-index: 9999 sometimes still render behind another element with a much lower z-index, like z-index: 1?

Hint: Think about stacking contexts specifically, and whether z-index values are ever compared globally across the entire page, or only within some more limited scope.

z-index values are never compared globally across an entire page, they're only ever meaningfully compared against other elements that share the exact same stacking context, a specific, bounded grouping that certain CSS properties on an ancestor element can create, isolating everything inside it into its own independent stacking layer. If an element with a very high z-index, like 9999, is nested inside an ancestor that itself created a new stacking context, say through a transform or a non-default opacity value, that high z-index only competes for stacking order against other elements within that same isolated context, it has absolutely no ability to compare against, or beat, elements belonging to an entirely separate, sibling stacking context, no matter how numerically small that sibling context's own internal z-index values happen to be. This is exactly why a seemingly enormous z-index can still lose to a much smaller one: the comparison that actually matters is which stacking context, as a whole, is ordered in front of which other one, and only secondarily, within that same context, which specific z-index value wins.

Exercises

MediumPractice using Z-index in a real scenario.
View Solution
.modal {
  position: fixed;
  z-index: 1000;
}

.overlay {
  position: fixed;
  z-index: 999;
}

Frequently Asked Questions

Why can an element with z-index: 9999 sometimes still render behind another element with a much lower z-index, like z-index: 1?

z-index values are never compared globally across an entire page, they're only ever meaningfully compared against other elements that share the exact same stacking context, a specific, bounded grouping that certain CSS properties on an ancestor element can create, isolating everything inside it into its own independent stacking layer. If an element with a very high z-index, like 9999, is nested inside an ancestor that itself created a new stacking context, say through a transform or a non-default opacity value, that high z-index only competes for stacking order against other elements within that same isolated context, it has absolutely no ability to compare against, or beat, elements belonging to an entirely separate, sibling stacking context, no matter how numerically small that sibling context's own internal z-index values happen to be. This is exactly why a seemingly enormous z-index can still lose to a much smaller one: the comparison that actually matters is which stacking context, as a whole, is ordered in front of which other one, and only secondarily, within that same context, which specific z-index value wins.

Related Functions

PositionTop, Right, Bottom, LeftOpacity