CSS Z-Index

Understanding and Using Z-Index in CSS

1. Basic Z-Index

The `z-index` property determines the stack order of an element. Higher values appear above lower ones.

/* Basic Z-Index */
.basic-container {
    position: relative;
    width: 300px;
    height: 200px;
    background-color: lightgray;
}
.box-1 {
    position: absolute;
    background-color: red;
    z-index: 1;
    width: 100px;
    height: 100px;
    top: 20px;
    left: 20px;
}
.box-2 {
    position: absolute;
    background-color: green;
    z-index: 2;
    width: 100px;
    height: 100px;
    top: 40px;
    left: 40px;
}
.box-3 {
    position: absolute;
    background-color: blue;
    z-index: 0;
    width: 100px;
    height: 100px;
    top: 60px;
    left: 60px;
}
        

Result:

Z-Index: 1
Z-Index: 2
Z-Index: 0

2. Negative Z-Index

Elements with a negative `z-index` appear behind elements with a `z-index` of 0 or higher.

/* Negative Z-Index */
.negative-container {
    position: relative;
    width: 300px;
    height: 200px;
    background-color: lightgray;
    overflow: hidden; /* Ensure containment */
}
.background-box {
    position: absolute;
    z-index: -1;
    background-color: lightblue;
    width: 250px;
    height: 150px;
    top: 25px;
    left: 25px;
}
.foreground-box {
    position: absolute;
    z-index: 0;
    background-color: orange;
    width: 200px;
    height: 100px;
    top: 50px;
    left: 50px;
}
        

Result:

Z-Index: -1
Z-Index: 0

3. Default Z-Index Behavior

If no `z-index` is specified, elements follow the stacking order of the DOM.

/* Default Z-Index */
.default-container {
    position: relative;
    width: 300px;
    height: 150px;
    background-color: lightgray;
}
.default-box-1 {
    background-color: orange;
    width: 100px;
    height: 100px;
    display: inline-block;
}
.default-box-2 {
    background-color: purple;
    width: 100px;
    height: 100px;
    display: inline-block;
}
        

Result:

Box 1
Box 2

4. Context of Stacking

A `z-index` creates a new stacking context for child elements.

/* Stacking Context */
.stacking-container {
    position: relative;
    width: 300px;
    height: 200px;
    background-color: lightgray;
}
.parent {
    position: relative;
    z-index: 1;
    background-color: lightblue;
    padding: 20px;
}
.child {
    position: absolute;
    z-index: -1;
    background-color: lightgreen;
    width: 100px;
    height: 100px;
}
        

Result:

Parent
Child

5. Z-Index and Fixed Position

Elements with `position: fixed` and a higher `z-index` stay above others relative to the viewport.

/* Fixed Position Z-Index */
.fixed-container {
    position: relative;
    width: 300px;
    height: 200px;
    background-color: lightgray;
    overflow: hidden; /* Ensures fixed element stays inside */
}
.fixed-box {
    position: fixed;
    z-index: 10;
    background-color: yellow;
    width: 100px;
    height: 50px;
    top: 0;
    left: 0;
}
.static-box {
    position: relative;
    z-index: 1;
    background-color: orange;
    width: 150px;
    height: 100px;
    top: 50px;
}
        

Result:

Fixed Box
Static Box

6. Z-Index and Overflow

Overflow properties may hide or clip elements with a high `z-index`.

/* Overflow and Z-Index */
.overflow-container {
    position: relative;
    overflow: hidden;
    width: 150px;
    height: 150px;
    background-color: lightgray;
}
.overflow-box {
    position: absolute;
    z-index: 5;
    background-color: orange;
    width: 200px;
    height: 200px;
}
        

Result:

Overflow Box

7. Z-Index and Opacity

Elements with opacity less than 1 create their own stacking context.

/* Opacity and Z-Index */
.opacity-container {
    position: relative;
    width: 300px;
    height: 200px;
    background-color: lightgray;
}
.opacity-box {
    position: relative;
    opacity: 0.8;
    z-index: 3;
    background-color: teal;
    width: 100px;
    height: 100px;
}
        

Result:

Opacity Box

8. Combining Position and Z-Index

`z-index` has no effect on unpositioned elements.

/* Position and Z-Index */
.unpositioned-container {
    position: relative;
    width: 300px;
    height: 200px;
    background-color: lightgray;
}
.unpositioned-box {
    z-index: 10;
    background-color: lightcoral;
    width: 100px;
    height: 100px;
}
        

Result:

Unpositioned Box

9. Z-Index and Inline Elements

Inline elements can use `z-index`, but they must be positioned (`relative`, `absolute`, etc.) for it to work.

/* Z-Index with Inline Elements */
.inline-container {
    position: relative;
    width: 300px;
    height: 100px;
    background-color: lightgray;
}
.inline-text {
    position: relative;
    z-index: 5;
    color: white;
    background-color: black;
    padding: 5px;
}
        

Result:

Normal text Z-Indexed Inline normal text.

10. Parent-Child Z-Index Behavior

Child elements cannot exceed their parent's stacking context, even with a higher `z-index`.

/* Parent-Child Z-Index */
.parent-container {
    position: relative;
    background-color: lightgray;
    width: 200px;
    height: 200px;
}
.parent {
    position: relative;
    z-index: 1;
    background-color: lightblue;
    padding: 20px;
}
.child {
    position: absolute;
    z-index: 10;
    background-color: orange;
    width: 100px;
    height: 100px;
}
        

Result:

Parent
Child

11. Z-Index and Transform

Elements with a `transform` property create a new stacking context.

/* Z-Index with Transform */
.transform-container {
    position: relative;
    width: 200px;
    height: 200px;
    background-color: lightgray;
}
.transformed {
    position: relative;
    transform: scale(1.2);
    z-index: 5;
    background-color: blue;
    color: white;
    width: 150px;
    height: 150px;
}
        

Result:

Transformed Box

12. Absolute vs Relative Z-Index

`z-index` works with both `absolute` and `relative` positioning, depending on the stacking context.

/* Position and Z-Index */
.relative-absolute-container {
    position: relative;
    width: 200px;
    height: 200px;
    background-color: lightgray;
}
.relative-box {
    position: relative;
    z-index: 3;
    background-color: red;
    width: 100px;
    height: 100px;
}
.absolute-box {
    position: absolute;
    z-index: 2;
    background-color: green;
    width: 100px;
    height: 100px;
    top: 20px;
    left: 20px;
}
        

Result:

Relative Box
Absolute Box

13. Z-Index Best Practices

Use a container to manage stacking contexts and prevent uncontrolled overlapping of elements.

/* Best Practices */
.best-practices-container {
    position: relative;
    width: 300px;
    height: 200px;
    background-color: lightgray;
}
.header {
    position: absolute;
    z-index: 100;
    background-color: white;
    width: 100%;
    height: 50px;
}
.modal {
    position: absolute;
    z-index: 200;
    background-color: lightblue;
    width: 150px;
    height: 100px;
    top: 60px;
    left: 75px;
}
        

Additional Resources