w3c规范里的stacking context,译做层叠上下文,最主要的做用仍是用来比较一个拥有定位元素(position:!static
)的元素的z轴层叠关系(z-index)。css
先上一个经典的例子:html
http://jsbin.com/pupibo/11/edit][1]web
代码:wordpress
html:flex
<div><span id="a">A z-index:1;</span></div> <div><span id="b">B</span></div> <div><span id="c">C</span></div>
cssspa
#a,#b,#c{ position:absolute; width:200px; height:100px; } #a{ left:20px; top:20px; background:yellow; z-index:1; } #b{ left:50px; top:50px; background:pink; } #c{ left:80px; top:80px; background:cyan; }
效果:code
问题:在不给#b
#c
设置z-index
的状况下,如何让#a
置于其余二者的后面?orm
答案你知道的,给包裹#a
的div
增长样式:htm
div:first-of-type{ opacity:0.9999; }
其实这里就涉及到堆叠上下文的概念了。context这个名词在css相关规范里见得多了,最著名的有块级格式上下文(block formatting context)。那么什么是上下文(context)呢?按个人理解,应该是某种相似环境的东西,一旦一个元素被加入一个context,他们的某些属性值会放在一块儿比较,最终的比较结果会影响到他们的视觉呈现。ci
而处于同一个堆叠格式上下文内的元素,它们会相互比较本身在z轴叠放的顺序,从而知道谁应该在谁的上面、谁应该在谁的下面(贵圈真乱 (。・д・。) ):
同一个层叠上下文中,层叠级别(即z-index属性值)大的显示在上面,反之显示在下面。
同一个层叠上下文中,层叠级别相同的两个元素,依据它们在HTML文档流中的顺序,写在后面的将会覆盖前面的。
那么问题来了,可不可能产生一个新的层叠上下文?
固然可能,根据规范,如下状况将会产生一个新的层叠上下文:
当一个元素是文档的根元素时,在完整的html文档里,根元素是html
标签;
当元素拥有一个值为非static
的position
且拥有一个值为非auto
的z-index
样式时;
当元素拥有一个值小于1
的opacity
样式时;
当元素拥有一个值不为none
且有效的transform
样式时;
当元素拥有一个值为display:flex|inline-flex
的样式且z-index
不为auto
时;
当元素拥有一个值不为normal
的mix-blend-mode
样式时;
当元素拥有一个值为isolate
的isolation
样式时;
当元素的will-change
样式指定为上述任意一个值时;
在移动端,当元素拥有一个值为touch
的-webkit-overflow-scrolling
值时;
当元素的filter
(此处为CSS3的滤镜)值不为none
时;
在 IE6,7 下,当元素拥有一个值为非static
的position
的样式时,即便z-index
未定义。
所以,元素的层叠关系不只与它在堆叠上下文中所属的层叠级别有关,还与它所在的堆叠上下文的顺序有关。这就是上面例子的所有秘密。而前文中的例子,其实还有另外一种方法,对,给div:first-of-type
添加transform:transform-function
样式。
最后,看到特意给ie6/7加粗的那条了吗?嗯,这就是ie6/7那个著名bug的根源,具体bug解剖请看张鑫旭大大2009年的一篇文章:ie6下z-index犯癫不起做用bug的初步研究,或者@doyoe的这个简单的demo。
最后附上这道题答案的效果:
效果图: