CSS:Stacking Context
通常情况下,HTML页面可以被认为是二维的,因为文本,图像和其他元素被排列在页面上而不重叠。在这种情况下,只有一个渲染进程,所有元素都知道其他元素所占用的空间。z-index属性可让你在渲染内容时调整对象分层的顺序,相信大部分人都用过position,当父元素设置了position,子元素设置position:absolute,默认是覆盖在元素上的,其实里面就隐藏了z-index的应用,今天来彻底了解这个z-index。
这边先讲个概念:层叠上下文,什么是层叠上下文:这边可以讲层叠上下文理解成一个属性,只有触发了某些特定条件才能激发这个属性,网页中有很多很多的元素,一个网页就是一个dom树,除了root(根结点),每个元素注定有父级,一个父级含有层叠上下文这个属性并且离当前元素最近,这个父元素就称为当前元素的层叠上下文容器,这里的概念和绝对定位概念一样,绝对定位是寻找当前元素最近的父元素并且含有position的属性(除了值为static)作为定位位置。
我们经常在布局时没有用到z-index,但是也能搞出我们想要的结果,比如:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head><style type="text/css"> div {
font: 12px Arial;
} span.bold { font-weight: bold; } #normdiv {
height: 70px;
border: 1px dashed #999966;
background-color: #ffffcc;
margin: 0px 50px 0px 50px;
text-align: center;
} #reldiv1 {
opacity: 0.7;
height: 100px;
position: relative;
top: 30px;
border: 1px dashed #669966;
background-color: #ccffcc;
margin: 0px 50px 0px 50px;
text-align: center;
} #reldiv2 {
opacity: 0.7;
height: 100px;
position: relative;
top: 40px;
left: 20px;
border: 1px dashed #669966;
background-color: #ccffcc;
margin: 0px 50px 0px 50px;
text-align: center;
} #absdiv1 {
opacity: 0.7;
position: absolute;
width: 150px;
height: 350px;
top: 10px;
left: 10px;
border: 1px dashed #990000;
background-color: #ffdddd;
text-align: center;
} #absdiv2 {
opacity: 0.7;
position: absolute;
width: 150px;
height: 350px;
top: 10px;
right: 10px;
border: 1px dashed #990000;
background-color: #ffdddd;
text-align: center;
} </style></head> <body> <br /><br /> <div id="absdiv1">
<br /><span class="bold">DIV #1</span>
<br />position: absolute;
</div> <div id="reldiv2">
<br /><span class="bold">DIV #3</span>
<br />position: relative;
</div> <div id="reldiv1">
<br /><span class="bold">DIV #2</span>
<br />position: relative;
</div> <div id="absdiv2">
<br /><span class="bold">DIV #4</span>
<br />position: absolute;
</div> <div id="normdiv">
<br /><span class="bold">DIV #5</span>
<br />no positioning
</div> </body></html>
运行结果:

上面所有元素都没有设置z-index,其实都是默认值:auto,按照MDN讲的:
当没有元素包含z-index属性时,元素按照如下顺序堆叠(从底到顶顺序):
- 根元素的背景和边界
- 普通流(无定位)里的块元素(没有position或者position:static;)按HTML中的出现顺序堆叠
- 定位元素按HTML中的出现顺序堆叠
基本是按照HTML出现顺序堆叠的。
我们再来开个例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style> html{
background-color: gray;
}
.test{
width: 300px;
height: 300px;
background-color: deepskyblue;
} </style>
<body>
<div class="test">
<!-- img属于行内替换元素,可设置width,height -->
<img src="test01.jpg" width="100px" height="100px" >
</div>
</div>
</body>
</html>

~嗯,这很正常,按照顺序,后面覆盖前面的,现在在img上面加个:z-index: -1;我以为它会跑div下面去,然而并没有任何改变,我们再加个position:relative;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style> html{
background-color: gray;
}
.test{
width: 300px;
height: 300px;
background-color: deepskyblue;
}
img:nth-child(1){
z-index: -1;
position: relative;
}
</style>
<body>
<div class="test">
<img src="test01.jpg" width="100px" height="100px" >
</div>
</div>
</body>
</html>

不见了,跑下面去了,为了让它更值观点,设置left:250px;

还真的在下面,为什么加了position:relative后,z-index才起作用?
借用张鑫旭的关于z-index的一句话:对于包含有position:relative/position:absolute的定位元素,以及FireFox/IE浏览器(不包括Chrome等webkit内核浏览器)(目前,也就是2016年初是这样)下含有position:fixed声明的定位元素,当其z-index值不是auto的时候,会创建层叠上下文,也就是说普通元素使用z-index是没有作用的。
这里有个层叠顺序图:

按照上面的顺序,background是最低层,为什么图片还会比它更低?这是因为当前的层叠上下文容器不是<div class="test"></div>,还记得上面讲过,寻找层叠上下文的机制跟position:absolute简直一样,所有一直向上找,知道根结点html,因为html默认包含层叠上下文这个属性,所以结果就是那样了。
我们可以给div触发层叠上下文,这样图片就又浮上来了:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style> html{
background-color: gray;
}
.test{
width: 300px;
height: 300px;
background-color: deepskyblue;
/*触发层叠上下文*/
/*混合模式*/
mix-blend-mode: exclusion;
/*触发层叠上下文*/
/*opacity: 0.9;*/
/*触发层叠上下文*/
/* position: absolute;
z-index: 0;
*/
/*触发层叠上下文*/
/*transform:rotate(1deg);*/
img:nth-child(1){
z-index: -1;
position: relative;
left: 250px;
}
</style>
<body>
<div class="test">
<img src="test01.jpg" width="100px" height="100px" >
</div>
</div>
</body>
</html>

借用张鑫旭的测试结果,因为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.
但是我们只要记我们常用的就好了。
还有一个要注意的是,两个层叠上下文里面的子元素的z-index没有可比性,一切得看父元素。
比如A元素有a,b,c;
B元素有d,e,f;
当A的z-index比B高时,B里面的d,e,f的z-index再怎么高都不会比A中任意一个元素高。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style> html{
background-color: gray;
}
.test01{
width: 300px;
height: 300px;
background-color: deepskyblue;
position: absolute;
z-index: 2;
}
.test01 img{
z-index: 10;
position: absolute;
left: 250px;
}
.test02{
position: absolute;
top: 80px;
left: 400px;
width: 300px;
height: 300px;
z-index: 1;
background-color: orange;
}
.test02 img{
z-index: 100;
position: absolute;
left: 250px;
}
</style>
<body>
<div class="test01">
父级z-index:2
图片z-index:10
<img src="test01.jpg" width="100px" height="100px" >
</div>
</div>
<div class="test02">
父级z-index:1
图片z-index:100
<img src="test02.jpg" width="100px" height="100px">
</div>
</body>
</html>

如上图所示,现在讲第二个div移到第一个div一样的位置,将css中的.test02的left:400p去掉,看下哪个图片在上面:

嗯,结果跟我们想的一样,z-index在平时我们不怎么写,但其实到处都在用,就说个最简单的例子,我们要让一些文本围着一张图片说明:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style>
.test{
width: 500px;
height: 500px;
border: 1px solid black;
}
.test img{
float: left;
margin-right:-50px;
}
</style>
<body> <div class="test">
这是对张图片的说明这是对张图片的说明这是对张图片的说明这是对张图片的说明
这是对张图片的说明这是对张图片的说明这是对张图片的说明这是对张图片的说明
<img src="test01.jpg" width="100px" height="100px">
这是对张图片的说明这是对张图片的说明这是对张图片的说明这是对张图片的说明
这是对张图片的说明这是对张图片的说明这是对张图片的说明这是对张图片的说明
</div>
</body>
</html>

讲下原理:因为img加了float所以脱离了普通流,进入了浮动流,除了块级元素看不到浮动流,其他元素都可以看到浮动流,所以文字就飘过去了,又因为加了margin-right:-50px;因为浮动不能超过父元素,所以文字有可以向左移动50px,但是图片还是那。对应上面的层叠顺序图,结果符合。那为什么要这样设计(得问设计者),因为文字(inline)是网页中比较重要的一个元素,所以z-index地位就比较高一点。

本文简化张鑫旭写的:深入理解CSS中的层叠上下文和层叠顺序
有错的话,欢迎指正
CSS:Stacking Context的更多相关文章
- 层叠上下文 Stacking Context
层叠上下文 Stacking Context 在CSS2.1规范中,每个盒模型的位置是三维的,分别是平面画布上的x轴,y轴以及表示层叠的z轴.对于每个html元素,都可以通过设置z-index属性来设 ...
- CSS——关于z-index及层叠上下文(stacking context)
以下内容根据CSS规范翻译. z-index 'z-index'Value: auto | <integer> | inheritInitial: autoApplies to: posi ...
- 关于stacking context和CSS z-index的总结
HTML中决定元素叠加顺序的CSS属性最有名的应该是z-index了.但是,往往在项目中发现有些情况和我们的预期不太一致.经过研究和学习,总算搞清楚了其中的关系.简单总结如下: 只有Positione ...
- 层叠上下文(The stacking context)
MDNThe stacking context 层叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的z轴上延伸,HTML元素依据其自身属性按照优 ...
- CSS - 层叠上下文(The stacking context)
对 MDN 的上的例子的拓展 Root - DIV #1(z-index: 5) - DIV #2(z-index: 2) - DIV #3(z-index: 4) - DIV #4(z-index: ...
- The stacking context
文档中的层叠上下文由满足以下任意一个条件的元素形成: 1. z-index 值不为 "auto"的 绝对/相对定位. 2. position位fixed. 3. opacity 属 ...
- 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 谈谈一些有趣的CSS题目(二)-- 从条纹边框的实现谈盒子模型
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- CSS 3 学习——transform 3D转换渲染
以下内容根据官方规范翻译,没有翻译关于SVG变换的内容和关于矩阵计算的内容. 一般情况下,元素在一个无景深无立体感的平面(flat plane)上渲染,这个平面就是其包含块所处的平面.同时,页面上的其 ...
随机推荐
- Linux内核TSS的使用
参见文章:http://blog.chinaunix.net/uid-22695386-id-272098.html linux2.4之前的内核有进程最大数的限制,受限制的原因是,每一个进程都有自已的 ...
- upc组队赛5 Assembly Required【思维】
Assembly Required 题目描述 Princess Lucy broke her old reading lamp, and needs a new one. The castle ord ...
- Config JAVA evironment for LoadRunner
1. Install jdk 2. Set system variables eg. JAVA_HOME = C:\Program Files (x86)\Java\jdk1.6.0_43 class ...
- 一份详尽的 Java 问题排查工具清单,值得收藏!
| grep 5 -A 3 #上匹配seq 10 | grep 5 -B 3 #下匹配seq 10 | grep 5 -C 3 #上下匹配,平时用这个就妥了cat f.txt | g ...
- 多线程实现奇偶统计v2 - 信号量实现
#include <stdio.h> #include <stdlib.h> #include <time.h> #include "pthread.h& ...
- Spring定时器StopWatch
简单总结一句,Spring提供的计时器StopWatch对于秒.毫秒为单位方便计时的程序,尤其是单线程.顺序执行程序的时间特性的统计输出支持比较好.也就是说假如我们手里面有几个在顺序上前后执行的几个任 ...
- CSS 中 transform、animation、transition、translate的区别
在前端页面的开发过程中,经常会碰到这么几个 CSS 属性容易搞混:transform.translate.animation还有transition.下面就针对这几个 CSS 属性做一个对比,辨别这几 ...
- 【记录】利用Jquery 在 textarea 内实现文字动态换行
背景: 最近在做前端时候遇到一种情况,需要用js动态输入内容到textarea, 比如实时聊天功能,用户A每次发送信息都需要另起一行. 问题: 根据以往经验,以为用$('#textArea').htm ...
- 2018-8-10-WPF-DrawingVisual
title author date CreateTime categories WPF DrawingVisual lindexi 2018-08-10 19:16:53 +0800 2018-2-1 ...
- (转)Unity Cinemachine插件,实现单目标和多目标之间切换
Unity Cinemachine插件学习笔记,实现单目标和多目标之间切换*版本要求Unity2017.1及以上. 参考资料: [官方] Unity 2017.1正式版发布 Cinemachine插件 ...