1

w3c规范里的stacking context,译作层叠上下文,最主要的作用还是用来比较一个拥有定位元素(position:!static)的元素的z轴层叠关系(z-index)。

先上一个经典的例子:

http://jsbin.com/pupibo/11/edit][1]

代码:

html:

  <div><span id="a">A z-index:1;</span></div>
  <div><span id="b">B</span></div>
  <div><span id="c">C</span></div>

css

#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;
}

效果:

demo 1

问题:在不给#b #c设置z-index的情况下,如何让#a置于其他两者的后面?

答案你知道的,给包裹#adiv增加样式:

  div:first-of-type{
    opacity:0.9999;
  }

其实这里就涉及到堆叠上下文的概念了。context这个名词在css相关规范里见得多了,最著名的有块级格式上下文(block formatting context)。那么什么是上下文(context)呢?按我的理解,应该是某种类似环境的东西,一旦一个元素被加入一个context,他们的某些属性值会放在一起比较,最终的比较结果会影响到他们的视觉呈现。

而处于同一个堆叠格式上下文内的元素,它们会相互比较自己在z轴叠放的顺序,从而知道谁应该在谁的上面、谁应该在谁的下面(贵圈真乱 (。・д・。) ):

  • 同一个层叠上下文中,层叠级别(即z-index属性值)大的显示在上面,反之显示在下面。

  • 同一个层叠上下文中,层叠级别相同的两个元素,依据它们在HTML文档流中的顺序,写在后面的将会覆盖前面的。

那么问题来了,可不可能产生一个新的层叠上下文?

当然可能,根据规范,以下情况将会产生一个新的层叠上下文:

  • 当一个元素是文档的根元素时,在完整的html文档里,根元素是html标签;

  • 当元素拥有一个值为非staticposition且拥有一个值为非autoz-index样式时;

  • 当元素拥有一个值小于1opacity样式时;

  • 当元素拥有一个值不为none且有效的transform样式时;

  • 当元素拥有一个值为display:flex|inline-flex的样式且z-index不为auto时;

  • 当元素拥有一个值不为normalmix-blend-mode样式时;

  • 当元素拥有一个值为isolateisolation样式时;

  • 当元素的will-change样式指定为上述任意一个值时;

  • 在移动端,当元素拥有一个值为touch-webkit-overflow-scrolling值时;

  • 当元素的filter(此处为CSS3的滤镜)值不为none时;

  • IE6,7 下,当元素拥有一个值为非staticposition的样式时,即使z-index未定义。

因此,元素的层叠关系不仅与它在堆叠上下文中所属的层叠级别有关,还与它所在的堆叠上下文的顺序有关。这就是上面例子的全部秘密。而前文中的例子,其实还有另一种方法,对,给div:first-of-type添加transform:transform-function样式。

最后,看到特地给ie6/7加粗的那条了吗?嗯,这就是ie6/7那个著名bug的根源,具体bug解剖请看张鑫旭大大2009年的一篇文章:ie6下z-index犯癫不起作用bug的初步研究,或者@doyoe的这个简单的demo

最后附上这道题答案的效果:

http://jsbin.com/pupibo/12

效果图:

demo 2


仅愚
484 声望7 粉丝