CSS 层叠上下文和层叠顺序原理分析及实战
1. 问题现象
最近在做一个网站的首页,首页的右上角有一个绝对定位的大动画,同时首页还有三个小动画,小动画部分的效果是:鼠标滑入特定区域(如下图),展示动画。
由于 UI 提供的动画画布很大,所以遮盖住了下图所示特定区域的 div 元素;最外层 div 元素,包括三个部分:头部标题、设置了透明度的文本以及一段文本。
在 div 元素上设置 onmouse 事件后,诡异的事情发生了:只有鼠标滑入设置透明度的文本时,小动画才出现,滑入其他部分,小动画不出现。
这是为什么?
探究原因,是因为大动画部分设置了绝对定位以及 z-index,形成了层叠上下文,层叠水平高于普通元素,遮盖了 div 中的部分元素。
要解决上述问题,咱们需要先翻开书本,从层叠上下文和层叠顺序说起。
2. 层叠相关概念和原理
2.1 层叠上下文
它是一个三维的概念,在 CSS2.1 规范中,每个盒模型都可看做一个三维空间,分别为平铺在画布上的 X 轴、Y 轴以及表示层叠的 Z 轴。一般情况下,元素在页面上沿 X 轴 Y 轴平铺,用户察觉不到它们在 Z 轴上的层叠关系。而一旦元素发生堆叠,这时就能发现某个元素可能覆盖了另一个元素或者被另一个元素覆盖。
如果一个元素含有层叠上下文,那么这个元素则为层叠上下文元素。我们可以理解为这个元素比普通元素在 Z 轴上距离用户更近一些。
层叠上下文规则:
- 层叠上下文的层叠水平比普通元素要高;
- 层叠上下文可以嵌套,内部层叠上下文及其子元素的层叠水平受制于外部的层叠上下文;
- 层叠上下文和其兄弟元素相互独立,即在不同的层叠上下文中,元素的层叠顺序没有可比性;
- 不同的层叠上下文元素发生层叠的时候,元素的层叠水平由父级层叠上下文的层叠顺序决定;
2.2 层叠等级
在同一个层叠上下文中,它描述定义的是该层叠上下文中的层叠上下文元素在 Z 轴上的上下顺序。
当然,在普通元素中,也可以有层叠顺序,这时它描述定义的是这些普通元素在 Z 轴上的上下顺序。z-index 属性可以影响层叠水平,注意是“影响”,不是“决定”。
2.3 层叠顺序
以上的层叠上下文和层叠等级是概念,层叠顺序是指元素遵循的规则。在同一个层叠上下文中,其中的元素遵循下图的规则:
其中,border/background 为装饰属性,float 浮动盒子和 block 块状元素一般用作布局,inline/inline-block 内联元素包含的是网页内容。在网页中内容最重要,所以 inline/inline-block 的层叠等级顺序更高。
通过实例验证上述规则,结论如下:
1)负 index 的层叠等级大于层叠上下文、小于 block 块级水平盒子
可参考下文中 ” 一些新的 css 属性会形成层叠上下文 ” 中的第一个例子;
2)float 浮动盒子的层叠等级大于 block 水平盒子
复制代码
111111111111
3)inline/inline-block 水平盒子的层叠等级大于 float 浮动盒子
复制代码
4) 不依赖于 z-index 的层叠上下文的层叠等级大于行内元素的层叠等级 (注:此处由于 opacity 属性,形成层叠上下文)
复制代码
111111111111
5)正 index 的层叠等级大于不依赖于 z-index 的层叠上下文的层叠等级
复制代码
111111111111
2.4 层叠准则
- 在同一个层叠上下文中,如果元素具有明显的层叠水平标识时(如 z-index),层叠水平高的元素在上面,距离用户“最近”;
- 当两个元素的层叠水平一致、层叠顺序相同时,DOM 流后面的元素会覆盖前面的元素
2.5 层叠上下文的形成
1)页面根元素,本身就具有层叠上下文,称为根层叠上下文
2)定位元素的 z-index 为数值时会形成层叠上下文
- z-index:auto 时 :
复制代码
111111111111
z-index:auto 时未形成层叠上下文,绿色长方形的 z-index 较大,所以绿色长方形遮盖了红色长方形;
- z-index 的值为数值时 :
复制代码