The stacking rules of z-index
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:
- The root element (HTML)
- Elements with
position
set toabsolute
/relative
andz-index
notauto
- Elements with
position
set tofixed
/sticky
- Children of flex containers with
z-index
notauto
- Elements with
opacity
less than 1 - Elements with
transform
notnone
- 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):
- The root element of the stacking context
- Elements with
position
set torelative
/absolute
/fixed
and a negativez-index
- Block-level elements in normal flow
- Floating elements in normal flow
- Inline elements in normal flow
- Elements with
position
set torelative
/absolute
/fixed
andz-index
set toauto
- Elements with
position
set torelative
/absolute
/fixed
and a positivez-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
- In IE6/7,
select
elements always appear on top and cannot be overlapped by other elements. - Some older browsers may interpret
z-index
differently. - When using
transform
oropacity
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
- Avoid creating too many stacking contexts.
- Reduce unnecessary
z-index
settings. - 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
- Use browser developer tools to inspect stacking contexts.
- Add temporary borders for visualization.
- Use
outline
instead ofborder
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