z-index
z-index 属性只是影响层叠顺序属性的一个,还有其他的属性影响层叠规则。z-index 只能影响定位元素和 flex 盒子的孩子元素。
理解层叠上下文和层叠水平
层叠上下文
层叠上下文(stacking context),是 HTML 中一个三维的概念。
层叠水平
层叠水平(stacking level),决定了同一个层叠上下文中元素在 z 轴上显示的顺序。
理解元素的层叠顺序
在 CSS2.1 时,层叠顺序如图一。
图一 CSS 世界层叠顺序规则
- 位于最下面的 background/border 特指层叠上下文元素的边框和背景色。每一个顺序规则仅适用于当前层叠上下文元素。
- inline 水平盒子指包括 inline/inline-block/inline-table 元素的“层叠顺序”。
- 单从层叠水平 z-index:0 和 z-index:auto 可以看成一样的。但是二者子啊层叠上下文领域有着明显的区别。
为什么内联元素的层叠顺序比浮动元素和块级元素要高?
图二 CSS 世界层叠顺序类型标注
background/border 为装饰属性,块级元素和浮动元素一般用作布局,而内联元素是内容。网页是以图文显示为中心的,所以内联源的层叠顺序更高。
务必记住的层叠规则
当元素发生层叠时,其覆盖遵循以下规则:
- 谁大谁上:当有明显的水平标识的时候,如 z-index,在同一水平上下文中,层叠水平值大的那个覆盖小的。
- 后来居上:当元素的层叠水平一致、层叠顺序相同时,在 DOM 流中出于后面的元素会覆盖前面的元素。
深入了解层叠上下文
层叠上下文的特征
层叠上下文元素有如下特征:
- 层叠上下文的层叠水平比普通元素要高。
- 层叠上下文可以阻断元素的混合模式。
- 层叠上下文可以嵌套,内部层叠上下文及其所有元素均受限于外部的“层叠上下文”。
- 每个层叠上下文和兄弟独立。
- 每个层叠上下文自成体系,当元素发生层叠时,整个元素被认为是子啊父层叠上下文的层叠顺序中。
层叠上下文的创建
和块状格式化上下文一样,层叠上下文也基本上是由一些特定的 CSS 属性创建的。我总结为 3 个流派。
- 天生派:页面根元素天生具有层叠上下文,称为根层叠上下文。
- 正统派:z-index 值为数值的定位元素的传统“层叠上下文”。
扩招派:其他 CSS3 属性。
根层叠上下文
根层叠上下文指的是页面根元素,可以看成是元素。因此,页面中所有的元定处于至少一个“层叠结界”中。
- 定位元素与传统层叠上下文
对于 position 值为 relative/absolute 以及 Firefox/IE 浏览器(不包括 Chrome 器)下含有 position:fixed 声明的定位元素,当其 z-index 值不是 auto 的时候,会层叠上下文。
层叠上下文与层叠顺序
一旦普通元素具有了层叠上下文,其层叠顺序就会变高。它的层叠顺序需要分两种情况讨论:
- 如果层叠上下文元素不依赖 z-index 数值,则其层叠顺序是 z-index:auto,可看成 z-index:0 级别;
- 如果层叠上下文元素依赖 z-index 数值,则其层叠顺序由 z-index 值决定。 我们上面提供的层叠顺序图实际上还缺少其他重要信息。我又花工夫重新绘制了一个更完整的 7 阶层叠顺序图,如下图所示。
z-index 负值深入理解
z-index 负值的最终表现并不是单一的,而是与“层叠上下文”和“层叠顺序”密切相关。z-index 负值渲染的过程就是一个寻找第一个层叠上下文
元素的过程,然后层叠顺序止步于这个层叠上下文元素。
明白了这一点,就可以理解为何 z-index 负值隐藏元素有时候确实隐藏,但有时候又隐藏不掉了。
那 z-index 负值的作用:
- 可访问性隐藏。z-index 负值可以隐藏元素,只需要层叠上下文内的某一个父元素加个背景色就可以。
- IE8 下的多背景模拟。
- 定位在元素的后面。
z-index“不犯二”准则
对于非浮层元素,避免设置 z-index 值,z-index 值没有任何道理需要超过 2。
先讲一下为什么需要这个准则。
- 定位元素一旦设置了 z-index 值,就从普通定位元素变成了层叠上下文元素,相互 间的层叠顺序就发生了根本的变化,很容易出现设置了巨大的 z-index 值也无法覆盖其他素的问题。
- 避免 z-index“一山比一山高”的样式混乱问题。此问题多发生在多人协作以及后期维护的时候。
这里的“不犯二”准则,并不包括那些在页面上飘来飘去的元素定位, 弹框、出错提示、一些下拉效果等都不受这一准则限制。遵循“不犯二”准则的情况下,9 已经是个足够安全的值 了,浮层组件根本无须担心会被页面上某个元素层级覆盖。
参考
【1】CSS 世界@张鑫旭