您的位置:首页 > 其它

说一说z-index容易被忽略的那些特性

2016-12-06 11:27 344 查看

前言

关于
z-index
,每个人都会用,但大多人都不理解其真正的生效机制。最近做项目有很多用到
z-index
的地方,才发现以前用的一知半解,所以上网查了一些资料梳理了一下。

关于
z-index
的生效机制并不复杂,但如果不花一点时间研究其特点,有很多关键点容易被忽略。

问题

HTML文档中有三个
div
元素,每个
div
中存在一个
span
元素,三个
span
元素分别设置背景颜色为
red
green
,以及
blue
。然后每个
span
都设置为
position: absolute
,三个
span
的位置稍微错开以便可以仔细观察它们之间的堆叠顺序。然后将第一个
span
元素的
z-index
设置为1,其他两个不设置。具体代码如下:

<div>
<span class="red">Red</span>
</div>
<div>
<span class="green">Green</span>
</div>
<div>
<span class="blue">Blue</span>
</div>

<style>
.red, .green, .blue {
position: absolute;
width: 200px;
height: 200px;
}
.red {
background: red;
z-index: 1;
}
.green {
background: green;
top: 50px;
left: 50px;
}
.blue {
background: blue;
top: 100px;
left: 100px;
}
</style>




那么问题来了,尝试在不打破下述规则的前提下将red span置于blue和green span元素之下:

不改变HTML元素的标记

不添加或者改变任何元素的
z-index
属性

不添加或者改变任何元素的
position
属性

如果不了解
z-index
的一些特性,对于上述要求估计会有些烦恼。

解决方案

在第一个div(也就是red span)上面添加一个值小于1的
opacity
属性,如下所示:

div:first-child {
opacity: .99;
}


效果如下:



可以看到
opacity
属性影响到了元素的堆叠顺序,这里就要说一下元素的堆叠顺序了。

堆叠顺序

z-index
表面上的规则似乎很简单,有一个更大
z-index
的元素会叠放在较小的
z-index
元素上面。但事实并非如此,这个规则只适用于一个相对的范围。

在HTML文档中有一个不变的堆叠准则,任何一个元素都可以叠放在其他元素之上或者之下,决定元素叠放顺序的规则其实很清晰。

当不包含
z-index
属性和
position
属性时,规则很简单,所有元素的叠放顺序与其所在HTML文档中出现的先后顺序一致。(当然使用负
margin
来重叠内联元素的特例除外。)

当元素浮动
float
时,浮动块元素被放置于非定位块元素与定位块元素之间,具体的讲,浮动元素显示在普通流中的后代块元素之上,常规流中的后代行内元素之下。

当加入
position
位置属性时,所有具有
position
属性的元素及其子元素会显示在其他不具有
position
属性的元素上面。(本文中具有
position
属性的元素指代的均是元素的position属性的值为除了
static
的其他值,如
relative
absolute
。)

当引入z-index属性时,规则稍微变得复杂一点。

1)
z-index
只在设置了
position
属性的元素上有效,没有
position
属性的元素上的
z-index
属性均不生效。

2)
z-index
值会产生堆叠上下文。

堆叠上下文

拥有共同父元素的一组元素共同前移或者后移构成了一个堆叠上下文。每个堆叠上下文有一个单一的根元素,当元素上形成一个新的堆叠上下文时,堆叠上下文中的所有子元素按照堆叠顺序被局限在一个固定的区域内。一个堆叠上下文构成一个整体,其内部元素有相对不同的堆叠顺序,但与其他堆叠上下文比较时,只能整体上移或者下移。

通俗的讲,如果某个元素被置于其所在堆叠上下文的最底层,我们是没有办法让他显示在另一个拥有更高层的堆叠上下文元素之上的,哪怕你将其
z-index
设置为无限大。那构成一个堆叠上下文的规则是怎样的呢?有如下情况:

文档的根元素

元素拥有
position
属性(除
static
属性之外),同事设置了不为
auto
z-index
属性。

元素拥有
opacity
属性,且取值小于1

一些新的css属性,如
filter
css-regions
等需要离屏渲染的属性,均能使元素形成堆叠上下文。

指定
position:fixed
的元素,技术
z-index
auto


同一堆叠上下文内子元素的堆叠顺序

从底层到上层依次为:

堆叠上下文的根元素

设置了
position
属性,并且
z-index
为负的元素及其子元素,
z-index
值较大的元素置于较小元素之上,同等属性值的元素按照html中出现的先后顺序堆叠。

没有设置
position
的元素

设置了
position
属性,并且
z-index属性
auto
的元素。

设置了
position
属性,并且
z-index
属性为正值的元素。

不同堆叠上下文

堆叠上下文可以嵌入其他堆叠上下文。

每个堆叠上下文和他的统计上下文是独立的。

堆叠上下文中子元素按照前述顺序摆放。

堆叠上下文内部的子堆叠上下文的
z-index
只在父堆叠上下文中有意义。

最后

在阐述完堆叠上下文的形成、堆叠上下文之间的堆叠规则,堆叠上下文内的堆叠顺序后,让我们回到文章最开始的问题。

起初元素的叠放顺序如下:

<div>  //1
<span class="red"></span>    //6
</div>
<div>  //2
<span class="green"><span> //4
</div>
<div>  //3
<span class="blue"></span>  //5
</div>


当添加属性opacity: 0.99后,第一个div形成了一个新的堆叠上下文,red span成为了新的上下文中的第一个子元素。元素结构变为:

<div>  //1
<span class="red"></span>    //1.1
</div>
<div>  //2
<span class="green"><span> //4
</div>
<div>  //3
<span class="blue"></span>  //5
</div>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  z-index