CSS 中的层叠上下文

在使用 bootstrap 的模态框时,出现了半透明遮罩始终盖住模态框的情况,
只有把模态框的 HTML 写到 body 之下才恢复正常,
当时郁闷得对着屏幕举了半分钟的中指。(程序员最好看看佛经,学会清心寡欲)

后来有幸看到了张鑫旭在慕课网 CSS深入理解之 relative 的视频,
才算真正知晓了层叠上下文在 CSS 中的规则和运用技巧。

还有些名称比较类似的学术语言和概念,格式化上下文、执行上下文、音频上下文、2D上下文等,感兴趣地可以去搜一下玩玩。

废话有些多,下面就正式开始吧!

什么是层叠上下文和层叠水平

层叠上下文其实把它理解为 z 轴也没有问题,屏幕上面叠着一层层图层(不是所有的元素都是)。

层叠水平则表示同一层层叠上下文对应的图层。

创建层叠上下文

那么怎样才能产生层叠上下文,让它的 z 轴不一样呢?
以下情况会创建层叠上下文(随着 CSS3 属性还在增加,本表不全):

  • z-index 不为 auto 的 position 定位元素
  • z-index 不为 auto 的 flex
  • opacity 不为 1
  • transform 不为 none
  • perspective 不为 none
  • filter 不为 none
  • mix-blend-mode 不为 normal
  • 带有 isolation: isolate
  • will-change 不为 none
  • 带有 -webkit-overflow-scrolling: touch


CSS 中的层叠上下文_第1张图片
20171122221904

此例中 .box1 创建了层叠上下文,z 轴上就比普通元素层级更高了,因此覆盖了 .box2。

同级层叠水平下的层叠顺序

而当有两个层叠上下文时,它们就有了兄弟和父子关系(假设现在都处于同级层叠水平)。

当为兄弟关系时(层叠上下文的兄弟关系,非 DOM 的兄弟),它们总是 后者居上 的。



item1
item2
CSS 中的层叠上下文_第2张图片
20171122162647

当为父子关系时,子级就存在父级的“作用域”内了,父级高我才高,不然我再高也没用。


CSS 中的层叠上下文_第3张图片
20171122164912

注:此处 position: relative; 但不写 z-index: 0(即 z-index: auto),它会覆盖普通元素,但并不会创建层叠上下文。 下面这个也是类似的例子,

.box { position: relative; margin: 0 0 10px }
.item {
  position: relative;
  z-index: -1;
}
.box2 { z-index: 0; }
/ 只有 z-index 不为 auto 才创建层叠上下文 /
CSS 中的层叠上下文_第4张图片
20171123134429

不同级层叠水平下的层叠顺序

既 z-index 不为 auto 的情况,这时它们总是 谁大谁上 的。


CSS 中的层叠上下文_第5张图片
20171122173308

关于最初 BUG 的解读

回到最初那个 bootstrap 内容框在黑底下的问题,就很方便理解了。

.modal 和 .modal-backdrop 都定位了,成为了层叠上下文,而如果 .content 由于需要或误操作也创建了层叠上下文,那么 .content 和 .modal 就有了兄弟关系,谁后谁上+谁大谁上,最终造成黑底的层级高于了 .content 的层级,而 .modal 作为 .content 范围内子级也就因此被覆盖住了。

最终,要么我们把 .modal 从 .content 拿出放置于与 .modal-backdrop 同级,要么把 .content 的层级提高得比 .modal-backdrop 更大(如果 .content 还有背景色那就是另一回事了)。

所以个人认为 bootstrap 这样写是不好的,要遇上一个不懂层叠上下文的,想破头也不知道为什么。
我推荐下面的这种写法:(自创的,后来看 layui 等框架也是这样写的,看来我没做错)




就像张鑫旭大神所说,如果你理解了层叠上下文,那么就根本不需要把 z-index 设得很大了,1-2 足矣。

非层叠上下文的覆盖关系

在张大神的 此文 中存在着这样一张图,一直让我产生着奇怪的误解。

CSS 中的层叠上下文_第6张图片
zxx

后来才想通,这是非层叠上下文时的覆盖关系,但很容易让我们产生混淆。

比如 float / inline 等,和 relative 下 z-index 非 auto 一样,都是会产生覆盖,但不会创建层叠上下文。

里面的 background 和 z-index 真的实在是蛊惑人心,个人认为大可忽略不论。

你可能感兴趣的:(CSS 中的层叠上下文)