在编码的过程中,我们常常用z-index去控制元素的层叠顺序.那么我们真的了解它了吗?
z-index的语法:(参考W3C文档)
属性 | 值 |
---|---|
Value | auto integer inherit |
Initial | auto |
Applies to | positioned elements |
Inherited | no |
Percentages | N/A |
Media | visual |
Computed value | as specified |
要注意是:z-index只能应用于定位元素(即设置了position属性非static 值).
W3C的描述:(W3C原文)
每个元素都具有三维的空间坐标,除了水平和垂直位置外,还有一个”Z轴”坐标,通过改变”Z轴”的坐标,我们可以实现元素的层叠.
在文档中,每个元素仅属于一个层叠上下文。元素的层叠级别为整型,它描述了在相同层叠上下文中元素在Z轴” 上的呈现顺序。
同一层叠上下文中,层叠级别大的显示在上,层叠级别小的显示在下,相同层叠级别时,遵循后来居上的原则,即其在HTML文档中的顺序。
不同层叠上下文中,元素呈现顺序以父级层叠上下文的层叠级别来决定呈现的先后顺序,与自身的层叠级别无关。
层叠上下文的创建:
The root element forms the root stacking context. Other stacking contexts are generated by any positioned element (including relatively positioned elements) having a computed value of ‘z-index’ other than ‘auto’. Stacking contexts are not necessarily related to containing blocks. In future levels of CSS, other properties may introduce stacking contexts, for example ‘opacity’
-
意思是:
- 页面根元素会形成层叠上下文,其他层叠上下文的产生由z-index值不为auto的定位元素(positioned 非static).层叠上下文不一定与包含块有关。在新版本的CSS中,其他的一些属性也会产生层叠上下文,比如 ‘opacity’.
-
通俗地说:当某个元素的 z-index 未显式定义或者被指定为 auto 时,该元素不会产生新的局部层叠上下文。也就是说它可以和兄弟,祖先,后辈元素处在同一个堆叠上下文中,它们被放在一起比较层叠级别,儿子可以盖住祖先,父亲也可以盖住儿子,儿子甚至可以越过祖先,盖住祖先的兄弟,在层叠上下文中,它们是并级的关系。
- 都处于一个层叠上下文中的情况:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.a,.b,.c,.a1 {width:100px;height:100px;}
.a{
background: #28d67a;
}
.b{
background: #ccc;
margin-top: -80px;
margin-left: 50px;
}
.c{
background: #62d4ea;
margin-top: -50px;
margin-left: 30px;
}
.a1 {
height:50px;
background: #ffff00;
margin-left:20px;
margin-top: -10px;
z-index:333;//指定子元素的层叠值
position: relative;
}
</style>
</head>
<body>
<div class="a">
a
<div class="a1">
a1
</div>
</div>
<div class="b">b</div>
<div class="c">c</div>
</body>
</html>
效果图:
当父元素处于同一级的层叠上下文中,改变子元素的z-index可以覆盖父元素,父元素的兄弟元素等等….
- 处于不同层叠上下文中的情况:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.a,.b,.c,.a1 {width:100px;height:100px;}
.a{
position: relative;
z-index: 0;
background: #28d67a;
}
.b{
position: relative;
z-index: 1;
background: #ccc;
margin-top: -80px;
margin-left: 50px;
}
.c{
position: relative;
z-index: 1;
background: #62d4ea;
margin-top: -50px;
margin-left: 30px;
}
.a1 {
height:50px;
background: #ffff00;
margin-left:20px;
margin-top: -10px;
z-index:333;
position: relative;
}
</style>
</head>
<body>
<div class="a">
a
<div class="a1">
a1
</div>
</div>
<div class="b">b</div>
<div class="c">c</div>
</body>
</html>
效果图:
当父元素处于不同的层叠上下文中,如果父元素的z-index比兄弟元素的小,就算子元素的z-index再高也没什么用,始终是覆盖不了父元素的兄弟元素.
所以在这再次强调一下:
同一层叠上下文中,层叠级别大的显示在上,层叠级别小的显示在下,相同层叠级别时,遵循后来居上的原则,即其在HTML文档中的顺序。
不同层叠上下文中,元素呈现顺序以父级层叠上下文的层叠级别来决定呈现的先后顺序,与自身的层叠级别无关。
在每一个层叠上下文中,的层叠顺序:
1.the background and borders of the element forming the stacking context.
2.the child stacking contexts with negative stack levels (most negative first).
3.the in-flow, non-inline-level, non-positioned descendants.
4.the non-positioned floats.
5.the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
6.the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
7.the child stacking contexts with positive stack levels (least positive first).
根据上面的顺序画的图:
CSS3与新时代的层叠上下文
css3中的一些新属性也会影响层叠上下文;下面列出一下属性:
- z-index值不为auto的flex项(父元素display:flex|inline-flex).
- 元素的opacity值不是1.
- 元素的transform值不是none.
- 元素mix-blend-mode值不是normal.
- 元素的filter值不是none.
- 元素的isolation值是isolate.
- will-change指定的属性值为上面任意一个。
- 元素的-webkit-overflow-scrolling设为touch.
下面我用opacity来说明:
当opacity值小于1时,该元素会创建新的局部层叠上下文,也就是说它可以和定位元素进行层叠层别比较
当opacity值小于1时,该元素拥有层叠级别且相当于z-index:0或auto,但不能定义 z-index ,除非本身是定位元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.a,.b,.c,.a1 {width:100px;height:100px;}
.a{
opacity:0.9;
background: #28d67a;
}
.b{
background: #ccc;
margin-top: -80px;
margin-left: 50px;
}
.c{
background: #5c5c5c;
margin-top: -50px;
margin-left: 30px;
}
.a1 {
height:50px;
background: #ffff00;
margin-left:20px;
margin-top: -10px;
z-index:333;
position: relative;
}
</style>
</head>
<body>
<div class="a">
a
<div class="a1">
a1
</div>
</div>
<div class="b">b</div>
<div class="c">c</div>
</body>
</html>
效果:
通过上图的对吧,大家可以看得出差异在哪了吧.还有很多其他的属性,这里就不一一去说了.有什么错误的话,请指正.