阿里云主机折上折
  • 微信号
Current Site:Index > The stacking rules of z-index

The stacking rules of z-index

Author:Chuan Chen 阅读数:20562人阅读 分类: CSS

The z-index is a key property in CSS that controls the stacking order of elements, determining their display priority in the direction perpendicular to the screen. Understanding the stacking rules of z-index is crucial for resolving issues of element overlap on a page.

Basic Concepts of z-index

The z-index property accepts an integer value (positive, negative, or 0). The larger the value, the higher the element's level in the stacking context. By default, all elements have a z-index value of auto, which is equivalent to 0.

<div class="box box1">Box 1 (z-index: 10)</div>
<div class="box box2">Box 2 (z-index: 5)</div>
.box {
  position: absolute;
  width: 200px;
  height: 200px;
}
.box1 {
  z-index: 10;
  background: red;
}
.box2 {
  z-index: 5;
  background: blue;
}

In this example, the red box will overlap the blue box because its z-index value is larger.

Formation of Stacking Contexts

z-index only takes effect under specific conditions that create a new stacking context:

  1. The root element (HTML)
  2. Elements with position set to absolute/relative and z-index not auto
  3. Elements with position set to fixed/sticky
  4. Children of flex containers with z-index not auto
  5. Elements with opacity less than 1
  6. Elements with transform not none
  7. Other CSS properties like filter, perspective, clip-path, etc.
<div class="parent">
  <div class="child">Child</div>
</div>
.parent {
  position: relative;
  z-index: 0; /* Creates a stacking context */
}
.child {
  position: absolute;
  z-index: 100; /* Only compared within the parent's stacking context */
}

Stacking Order Rules

When elements are in the same stacking context, their z-index values are compared. When they are in different stacking contexts, the z-index values of their parent stacking contexts are compared.

Stacking order (from bottom to top):

  1. The root element of the stacking context
  2. Elements with position set to relative/absolute/fixed and a negative z-index
  3. Block-level elements in normal flow
  4. Floating elements in normal flow
  5. Inline elements in normal flow
  6. Elements with position set to relative/absolute/fixed and z-index set to auto
  7. Elements with position set to relative/absolute/fixed and a positive z-index
<div class="stacking-context">
  <div class="box neg-z">Negative z-index</div>
  <div class="box normal">Normal flow</div>
  <div class="box float">Float</div>
  <span class="inline">Inline</span>
  <div class="box auto-z">Auto z-index</div>
  <div class="box pos-z">Positive z-index</div>
</div>
.stacking-context {
  position: relative;
  z-index: 0;
}
.box {
  position: absolute;
  width: 150px;
  height: 150px;
}
.neg-z {
  z-index: -1;
  background: #ccc;
}
.normal {
  position: static;
  background: #aaa;
}
.float {
  float: left;
  background: #888;
}
.inline {
  background: #666;
}
.auto-z {
  z-index: auto;
  background: #444;
}
.pos-z {
  z-index: 1;
  background: #222;
}

Inheritance of z-index

z-index is not inherited by child elements. Each element's position in the stacking context is independent, and a child element's z-index is only effective within the stacking context created by its parent.

<div class="parent1">
  <div class="child1">Child 1</div>
</div>
<div class="parent2">
  <div class="child2">Child 2</div>
</div>
.parent1 {
  position: relative;
  z-index: 1;
}
.parent2 {
  position: relative;
  z-index: 2;
}
.child1, .child2 {
  position: absolute;
  width: 100px;
  height: 100px;
}
.child1 {
  z-index: 100;
  background: red;
}
.child2 {
  z-index: 1;
  background: blue;
}

Even though child1 has a large z-index value, because its parent parent1 has a smaller z-index than parent2, the entire parent1 stacking context is below parent2, so child2 will overlap child1.

Common Issues and Solutions

1. z-index Not Working

This is usually because the position property is not set or is set to static. z-index only works on elements with position set to relative/absolute/fixed/sticky.

/* Not working */
.not-working {
  z-index: 10;
  position: static;
}

/* Working */
.working {
  z-index: 10;
  position: relative;
}

2. Unexpected Stacking Order

When multiple stacking contexts are nested, seemingly illogical stacking orders may occur. In such cases, check the z-index values of each stacking context.

<div class="context-a" style="z-index: 1;">
  <div class="context-b" style="z-index: 100;">
    <!-- This element is actually within the context-a stacking context -->
  </div>
</div>
<div class="context-c" style="z-index: 2;">
  <!-- This element will overlap everything above -->
</div>

3. Modal Overlay Being Blocked

Modals should be placed as direct children of the body element, ensuring their z-index is greater than the maximum z-index of other elements on the page.

<body>
  <div class="content"></div>
  <div class="modal"></div>
</body>
.modal {
  position: fixed;
  z-index: 9999;
  /* Other styles */
}

Advanced Application Techniques

1. Using CSS Variables to Manage z-index

:root {
  --z-modal: 1000;
  --z-tooltip: 900;
  --z-dropdown: 800;
}

.modal {
  z-index: var(--z-modal);
}

2. Application of Negative z-index

Negative z-index can place elements below the background of their stacking context.

<div class="parent">
  <div class="background"></div>
  <div class="content"></div>
</div>
.parent {
  position: relative;
}
.background {
  position: absolute;
  z-index: -1;
}

3. Dynamic Calculation of z-index

Dynamically calculate the maximum z-index value in JavaScript:

function getMaxZIndex() {
  return Math.max(
    ...Array.from(document.querySelectorAll('body *'))
      .map(el => parseFloat(window.getComputedStyle(el).zIndex))
      .filter(zIndex => !isNaN(zIndex))
  );
}

Browser Compatibility Notes

  1. In IE6/7, select elements always appear on top and cannot be overlapped by other elements.
  2. Some older browsers may interpret z-index differently.
  3. When using transform or opacity to create a stacking context, behavior may vary in certain browsers.
/* Hack for IE6/7 */
* html .cover-select {
  position: relative;
  background: none;
  behavior: expression(
    this.runtimeStyle.background = "none",
    this.insertAdjacentHTML('beforeEnd', '<iframe style="position:absolute;z-index:-1;top:0;left:0;width:100%;height:100%;filter:alpha(opacity=0);"></iframe>'),
    this.runtimeStyle.behavior = 'none'
  );
}

Performance Optimization Tips

  1. Avoid creating too many stacking contexts.
  2. Reduce unnecessary z-index settings.
  3. Use CSS containment to optimize stacking contexts with many elements.
.optimized {
  contain: paint; /* Creates a containment block, limiting repaint scope */
  position: relative;
  z-index: 1;
}

Practical Case Studies

1. Multi-level Navigation Menu

<nav class="main-nav">
  <ul>
    <li>
      <a href="#">Menu 1</a>
      <ul class="submenu">
        <li><a href="#">Submenu 1</a></li>
        <li><a href="#">Submenu 2</a></li>
      </ul>
    </li>
  </ul>
</nav>
.main-nav {
  position: relative;
  z-index: 100;
}
.submenu {
  position: absolute;
  z-index: 101;
  display: none;
}
.main-nav li:hover .submenu {
  display: block;
}

2. Image Gallery Overlay Effect

<div class="gallery">
  <img src="image1.jpg" class="top">
  <img src="image2.jpg" class="middle">
  <img src="image3.jpg" class="bottom">
</div>
.gallery {
  position: relative;
  height: 300px;
  width: 400px;
}
.gallery img {
  position: absolute;
  transition: z-index 0.3s;
}
.top {
  z-index: 3;
}
.middle {
  z-index: 2;
}
.bottom {
  z-index: 1;
}
.gallery:hover .top {
  z-index: 1;
}
.gallery:hover .bottom {
  z-index: 3;
}

Debugging Tools and Techniques

  1. Use browser developer tools to inspect stacking contexts.
  2. Add temporary borders for visualization.
  3. Use outline instead of border for debugging (does not affect layout).
.debug * {
  outline: 1px solid rgba(255, 0, 0, 0.3);
}

In Chrome Developer Tools, you can view the page's stacking situation via "More tools" > "Layers" panel.

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.