CSS Z-Index

When CSS positioning moves elements so they overlap each other, the browser needs a rule to determine which element appears in front and which appears behind. This is controlled by the z-index property.

The name "z-index" comes from the concept of a Z-axis — an imaginary depth axis coming out of the screen toward the viewer. Elements with a higher z-index are "closer" to the viewer and appear in front.

How z-index Works

The z-index property accepts integer values (positive, negative, or zero). A higher number places the element on top, and a lower number (or negative) places it behind.

Important: z-index only works on elements that have a position value other than static. Without position: relative, absolute, fixed, or sticky, changing z-index will have no visible effect.

Basic Example

.box-a {
    position: absolute;
    top: 20px;
    left: 20px;
    z-index: 1;
    background-color: #3498db;
    width: 150px;
    height: 100px;
}

.box-b {
    position: absolute;
    top: 50px;
    left: 60px;
    z-index: 2;   /* Higher value — appears in front of box-a */
    background-color: #e74c3c;
    width: 150px;
    height: 100px;
}

Box B overlaps Box A and appears in front because its z-index is 2, which is higher than Box A's value of 1.

Default z-index Behavior

When no z-index is set, elements overlap in source order — an element that appears later in the HTML is rendered on top of one that appears earlier.

<!-- box-a appears first in HTML -->
<div class="box-a"></div>

<!-- box-b appears second — it overlaps box-a by default -->
<div class="box-b"></div>

Negative z-index

An element with a negative z-index is placed behind the default content layer, appearing behind normal in-flow elements.

.background-shape {
    position: absolute;
    z-index: -1;   /* Appears behind all other content */
    background-color: #f0e0ff;
    width: 200px;
    height: 200px;
    border-radius: 50%;
}

This technique is used for decorative background shapes that should appear behind the main content of a section.

Stacking Context

A stacking context is a self-contained layer in which z-index values are compared. Each stacking context is independent — z-index values from one context cannot be compared directly with values in another context.

A new stacking context is created when an element has:

  • A position other than static combined with a z-index value other than auto.
  • opacity less than 1.
  • transform, filter, or will-change applied.

Stacking Context Example

.container {
    position: relative;
    z-index: 10;   /* Creates a new stacking context */
}

.container .child {
    position: absolute;
    z-index: 9999;
    /* This element is only compared with siblings inside .container,
       NOT with elements outside of .container */
}

Even though the child has z-index: 9999, it cannot appear above elements outside .container that have a z-index higher than 10. This is the most common source of z-index confusion.

Practical Use Cases

Modal Overlay

.overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.6);
    z-index: 500;  /* Above all page content */
}

.modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: white;
    padding: 30px;
    border-radius: 10px;
    z-index: 600;  /* Above the overlay */
}

Fixed Navigation Bar

nav {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 1000;  /* Stays above all scrolled content */
    background-color: #1a1a2e;
}

Z-Index Scale Best Practices

Using a consistent z-index scale prevents conflicts and makes it easy to understand stacking order at a glance.

/* Example z-index scale */
/* Normal content:   0–9    */
/* Dropdowns:        100    */
/* Sticky elements:  200    */
/* Modals/overlays:  500–600 */
/* Notifications:    700    */
/* Tooltips:         800    */
/* Max (emergencies): 9999  */

Summary

z-index controls the vertical stacking order of overlapping positioned elements. Higher values bring elements to the front; negative values push them behind the default layer. It only works on elements with a position value other than static. Stacking contexts create isolated layers where z-index comparisons are local — understanding this explains most confusing z-index bugs. Using a consistent z-index scale across a project maintains order and avoids conflicts.

Leave a Comment

Your email address will not be published. Required fields are marked *