调整字号

z-index 层叠原理

z-index 这个属性,相信大家跟我一样,刚看到它的时候都觉得挺简单的,不过是 z 轴的值而已,越大就越靠前。但是实际用起来,往往又出现问题,得不到想要的结果。其实层叠的原理还是有必要深究一番的,至于如何搞清楚,最好的方法当然是看一看标准了。

首先,z-index 的值可以是 auto、整数或 inherit,默认值为 auto该属性只能用在定位元素上,也就是说,对静态定位元素使用 z-index 无效。当用户面朝显示器时,z-index 值越大的元素离用户越近,而具体的层叠规则,先要扯出一个概念:堆叠上下文(stacking context)。是不是联想到了块级格式化上下文(BFC)?在这我也将其简称为 SC 吧。

文档中的每个元素,都存在于一个 SC 中,根元素会生成一个根堆叠上下文(root stacking context),而对于其他元素,只有满足两个条件才会生成一个新的 SC:z-index 不为 auto 且必须是定位元素 (position 的值不为 staticSC 是可以嵌套的。

SC 是进行堆叠的基本单位。假如元素 A 生成了一个 SC,那么 A 的所有后代元素的堆叠顺序如下:

  1. A 的背景和边框
  2. z-index 为负值的各个 SC
  3. 静态定位的块级元素
  4. 静态定位的浮动元素
  5. 静态定位的行内元素,包括 inline table 和 inline block
  6. z-index 为 0 的子 SC,和 z-indexauto 的定位元素
  7. z-index 为正值的子 SC

其中顺序是由远到近的,即 1 在最下层,7 在最上层。需要注意的是,划分堆叠次序时,子 SC 内的元素都是作为一个整体参与堆叠,也就是各个 SC 中的元素不会串台,比如两个定位元素 A 和 B,z-index 值分别为 1 和 2,则 B 在 A 之上,并且 B 的后代元素,也都在 A 的后代元素之上。即使 A 中的某个后代设置了 z-index 为 9999,也会被 B 以及其后代所遮挡。所以说堆叠上下文是进行堆叠的基本单位,只有搞定了这一概念,才能理解元素是如何堆叠的。每个 SC 就像是一层楼,后代元素都处在这层楼里,不管后代有多高的 z-index 值,一楼的元素也永远不会遮挡二楼三楼的元素。

如果两个相邻的 SC,z-index 值相同,那么按照在文档树中的顺序,后面的会遮挡前面的。

IE 6/7 存在一个 bug,z-index 的默认值成了 0 而不是 auto。虽然在现代浏览器中,z-indexauto 的元素,堆叠等级也按 0 来处理,但这跟 z-index:0 还是存在一个区别,那就是 z-index:auto 不会生成 SC,而 z-index:0 会生成一个新的 SC,结果就会影响到后代元素,不管后代元素设置了多高的 z-index,都会被另一个 z-index:1 的元素所遮挡。请看 demo

或者说这个 bug 导致的结果是,有时候你发现 IE 6/7 中元素的 z-index 是相对于父元素的,不管怎么折腾都把它提不上去。所以需要特别注意。

先写这么多吧,希望能对大家有所帮助。

评论(2条)

smalldragonluo 2014年3月31日 , 15:24

谢谢

奇云tasty 2014年4月2日 , 16:17
flight