CSS3 中的层叠上下文初探

作者:HaoyCn
文章源自:https://segmentfault.com/a/1190000003825614

前言:关于层叠上下文,笔者还没有去阅读更详细的 W3C 规范来了解更本质的原理(表打我,等我校招拿到 offer 了我就读好伐 T_T)。一直听说 CSS3 里的层叠上下文有新情况,但没找到很好的参考资料,故自己实战一把。鉴于笔者水平有限,如有任何遗漏或者错误,则恳请读者斧正。

1 CSS2.1 中规定的层叠上下文

Background and borders — of the element forming the stacking context. The lowest level in the stack.

Negative Z-Index — the stacking contexts of descendants elements with negative z-index.

Block Level Boxes — in-flow non-inline-level non-positioned descendants.

Floated Boxes — non-positioned floats

Inline Boxes — in-flow inline-level non-positioned descendants.

Z-index: 0 — positioned elements. These form new stacking contexts.

Positive Z-index — positioned elements. The highest level in the stack.

图文来源:What You May Not Know About the Z-Index Property

现在该笔者上场翻译了!在解释上面术语之前,需要阐明两个术语:“定位”指的是positionrelativeabsolutefixed的元素,“非定位”则相反。

  • 背景和边框:建立层叠上下文元素的背景和边框。层叠中的最低级
  • 负 Z-indexz-index为负的后代元素建立的层叠上下文
  • 块级盒:文档流内非行内级非定位后代元素
  • 浮动盒:非定位浮动元素(笔者注:即排除了 position: relative的浮动盒)
  • 行内盒:文档流内行内级非定位后代元素
  • Z-index: 0:定位元素。这些元素建立了新层叠上下文(笔者注:不一定,详见后文)
  • 正 Z-index:(z-index为正的)定位元素。层叠的最高等级

引文如上所表。但笔者提醒各位读者一点,“Z-index: 0”级的定位元素不一定就会建立新的层叠上下文。因为:

CSS2.1:(z-index: auto)The stack level of the generated box in the current stacking context is 0. The box does not establish a new stacking context unless it is the root element.

当定位元素z-index: auto,生成盒在当前层叠上下文中的层级为0。但该盒不建立新的层叠上下文,除非是根元素。

规范是这样,但 IE6-7 有个 BUG,定位元素即便z-index: auto照样创建层叠上下文。

以上是基于 CSS2.1 的层叠上下文介绍。下面要阐述的是在 CSS3 新环境下,层叠上下文的新变化。

2 CSS3 带来的变化

总的来说变化可以归为两点,我们之后一一探讨:

  1. CSS3 中许多属性会创建局部层叠上下文
  2. tranform属性改变绝对定位子元素的包含块

2.1 产生新层叠上下文的情况

以下情况会产生新的层叠上下文:

  • 根元素(HTML)
  • 绝对或相对定位且z-index值不为auto
  • 一个伸缩项目Flex Item,且z-index值不为auto,即父元素display: flex|inline-flex
  • 元素的opacity属性值小于1
  • 元素的transform属性值不为none
  • 元素的mix-blend-mode属性值不为normal
  • 元素的filter属性值不为normal
  • 元素的isolation属性值为isolate
  • position: fixed
  • will-change中指定了上述任意属性,即便你没有直接定义这些属性元素的-webkit-overflow-scrolling属性值为touch

以上列表译自:

Understanding CSS z-index—The stacking context,提醒广大读者,别看中文版,因为中文版并非实时跟进更新的,且翻译不太准确

2.2 提升层叠上下文中的层级

以上元素建立新层叠上下文的同时,也会提升元素自身所在层叠上下文中的层级。

我们以opacity为例。来看下 CSS3 规范中的话:

If an element with opacity less than 1 is not positioned, implementations must paint the layer it creates, within its parent stacking context, at the same stacking order that would be used if it were a positioned element with ‘z-index: 0’ and ‘opacity: 1’. If an element with opacity less than 1 is positioned, the ‘z-index’ property applies as described in [CSS21], except that ‘auto’ is treated as ‘0’ since a new stacking context is always created.

如果元素opacity小于1且未定位,则必须在其父层叠上下文中,按其在定位了的z-index: 0opacity: 1的情况中的层叠顺序绘制。如果opacity小于1且已定位,z-index属性按 CSS2.1 应用,但auto要视为0,因为新的层叠上下文总是创建了的。

如下案例:

div {
    width: 100px;
    height: 100px;
}
#box1 {
    position: absolute;
    background: red;
    top: 40px;
    left: 40px;
}
#box2 {
    background: blue;
}

<body>
    <div id="box1"></div>
    <div id="box2"></div>
<body>

以上 CSS 和 HTML 片段中,由于 box1 是绝对定位(层级为“Z-index: 0”级),而 box2 是文档流内块级盒(层级为“块级盒”级),因此 box1 会层叠在 box2 之上。下面添加如下 CSS 规则:

#box2 {
    opacity: .5;
}

这时候, box2 则会层叠在 box1 之上了。因为 box2 的opacity0.5(小于 1),故视其为“Z-index: 0”级,也就和 box1 同级了。同级情况下,按照二者在源代码中的顺序,居后的 box2 又重新占领高地了。

读者可以取下面规则之任意一条实验,都能达到同样效果:

#box2 {
    transform: scale(1);
    mix-blend-mode: difference;
    isolation: isolate;
    -webkit-filter: blur(5px);
}

2.3 transform 改变绝对定位子元素包含块

transform除了建立新的局部层叠上下文外,还会干一件事:改变绝对定位子元素的包含块。须注意的是,固定定位也是绝对定位的一种。

什么是包含块?有时候一些盒子根据矩形盒计算自身定位和大小,此矩形盒即包含块。更多详情请阅读视觉格式化模型详述。

固定定位元素

固定定位元素的包含块由视口创建(如果读者了解视觉格式化模型详述的信息,也就知道这一点:在计算其“静态位置”的时候,则以初始化包含块作为其计算包含块)。现在我们看以下源代码:

div {
    width: 100px;
    height: 100px;
}
#fixed {
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background: blue;
}
#transform {
    background: red;
    padding: 20px;
}

<body>
    <div id="transform">
        <div id="fixed"></div>
    </div>
</body>

这个时候,以视口为包含块进行定位和大小计算, fixed将会铺满整个屏幕。

但现在,我们加上如下规则:

#transform {
    transform: scale(1);
}

此时,fixed的包含块不再是视口,而是transform的内边距盒的边缘盒了。故此时fixed的宽高均为140px

绝对定位元素

我们举一个例子:

#relative {
    position: relative;
    width: 100px;
    height: 100px;
    background: green;
}
#absolute {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background: blue;
}
#transform {
    background: red;
    width: 50px;
    height: 50px;
}

<div id="relative">
    <div id="transform">
        <div id="absolute"></div>
    </div>
</div>

此时absolute的包含块为relative的内边距盒的边缘盒。由此absolute的宽高均为100px。然后我们添加如下规则:

#transform {
    transform: scale(1);
}

由于transform创建了局部层叠上下文,absolute的包含块不再是 relative而是transform了,根据这一新的包含块,得新宽和高为50px

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,647评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,690评论 2 374
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,739评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,692评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,552评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,410评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,819评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,463评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,752评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,789评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,572评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,414评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,833评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,054评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,345评论 1 254
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,810评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,016评论 2 337

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,709评论 1 92
  • 引自:张鑫旭的博客本文地址:http://www.zhangxinxu.com/wordpress/?p=5115...
    destiny0904阅读 1,481评论 1 0
  • 1.z-index基础 z-index属性指定了元素及其子元素的[z顺序],而[z顺序]可以决定当元素发生覆盖的时...
    徐国军_plus阅读 6,312评论 1 6
  • z-index 与 css 定位属性 z-index 只对定位元素有作用。 如果定位元素z-index没有发生嵌套...
    soojade阅读 835评论 0 2
  • 因为一场梦境,那些渐被遗忘又悄悄显露的痴心杂念,继续叨扰着生活。半夜腾起也只为一场记起。人的痛苦或幸福在于,无论怎...
    青春被忘路阅读 154评论 0 0