前言
相信每一个前端小伙伴都使用 z-index 来做过一些蒙版的层级控制,但是你是否了解层叠上下文这个概念呢,你在使用 z-index 来控制层级的时候,有没有遇到过一些想不通的问题呢?如果有的话,不妨花点时间来了解 CSS 中的层叠规则。
一个小问题
现在设计提供了一个分享卡片样式:
<body>
<div class="card">
<div class="title">
我有下划线
</div>
</div>
</body>
复制代码
<style>
.card{
background:#fff;
}
.title {
position: relative;
width: 100px;
}
.title::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 8px;
background-image: linear-gradient(to left, rgb(238, 218, 148), rgb(217, 179, 91));
}
</style>
复制代码
页面效果如下:
.title::before {
content: '';
...
z-index:-1;
}
复制代码
再次查看页面效果:
层叠上下文
层叠上下文,英文称作 stacking context,是 HTML 中的一个三维的概念。如果一个元素含有层叠上下文,我们可以理解为这个元素在 z 轴上就“高人一等”。我们可以把层叠上下文理解为一种“层叠结界”,自成一个小世界。在这个层叠结界中,所有的层叠元素都不会溢出这个结界,并在其内部满足一定的层叠规则:
层叠上下文的特性
层叠上下文的层叠水平要比普通元素高
层叠上下文可以阻断元素的混合模式
层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的“层叠上下文”。
每个层叠上下文和兄弟元素独立,也就是说,当进行层叠变化或渲染的时候,只需要考虑后代元素。
每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中。
复制代码
层叠上下文的创建
层叠上下文可以由以下几种方式创建:
- 页面根元素天生具有层叠上下文,又称为根层叠上下文;
- 给元素设置 z-index 值为数值的定位元素;
- 给元素设置特定的 CSS3 属性,也会使其成为层叠上下文;
根层叠上下文
根层叠上下文指的是页面根元素,可以看成是元素。因此,页面中所有的元素一 定处于至少一个“层叠结界”中。
z-index 为数值的定位元素
对于 position 值为 relative/absolute 以及 Firefox/IE 浏览器(不包括 Chrome 浏览 器)下含有 position:fixed 声明的定位元素,当其 z-index 值不是 auto 的时候,会创建 层叠上下文。换言之,想让 z-index 对元素的层叠顺序生效,前提是该元素得是定位元素,否则根本都不会创建层叠上下文。
CSS3 属性创建的层叠上下文
- 元素为 flex 布局元素(父元素 display:flex|inline-flex),同时 z-index 值不是 auto。
- 元素的 opacity 值不是 1。
- 元素的 transform 值不是 none。
- 元素 mix-blend-mode 值不是 normal。
- 元素的 filter 值不是 none。
- 元素的 isolation 值是 isolate。
- 元素的 will-change 属性值为上面 2~6 的任意一个(如 will-change:opacity、will-chang:transform 等)。
- 元素的-webkit-overflow-scrolling 设为 touch。
层叠上下文与层叠顺序
因为根层叠上下文的存在,所有所有页面元素至少存在于一个层叠上下文中,并在其中满足一下规律:
- 如果层叠上下文元素不依赖 z-index 数值,则其层叠顺序是 z-index:auto,可看成 z:index:0 级别;由 CSS3 属性创建的层叠上下文属于此类情况;
- 如果层叠上下文元素依赖 z-index 数值,则其层叠顺序由 z-index 值决定。
更完整的 7 阶层叠顺序图:
消失的下划线
最后,我们一起看看消失的下划线去哪儿了,首先看一下页面的 dom 元素层级 body->card->title->title:before,而此时,页面中有两个层叠上下文,根层叠上下文和伪元素通过 z-index:-1 创建的层叠上下文,因为伪元素 z-index 值是负值,查阅层叠顺序图,可以知道伪元素会处于 body 的背景图之上,card(块状水平盒子)之下。而 card 元素的背景设置为纯白色,所以下划线伪元素就被 card 的白色背景挡住了,因此,我们已经找到了消失的下划线,那么怎么让下划线正好展示在文字和 title 元素的背景之间呢,那很简单,只需要给 title 元素设置样式:z-index:0,即给 title 元素创建层叠上下文,样式代码:
.title {
position: relative;
width: 100px;
z-index:0;
}
复制代码
此时页面效果:
最后
自己试试?codePen
参考:css世界-张鑫旭