CSS——关于z-index及层叠上下文(stacking context)
以下内容根据CSS规范翻译。
z-index
'z-index'
Value: auto | <integer> | inherit
Initial: auto
Applies to: positioned elements
Inherited: no
Percentages: N/A
Media: visual
Computed value: as specified
注意:z-index属性只能应用于position属性不为static的元素,即定位元素。
对于定位元素来说,z-index属性指定:
- 在当前层叠上下文中该定位元素盒子的堆叠层级(stack level);
- 该定位元素盒子是否形成新的层叠上下文(stacking context)。
z-index属性可取值的含义:
<integer>
如果值为整数,那么这个整数指的是这个盒子(the generated box)在当前层叠上下文中的堆叠层级。同时,这个盒子对内也形成一个层叠上下文。
auto
如果值为auto,那么这个盒子(the generated box)在当前层叠上下文中的堆叠层级为0。同时,这个盒子对内不形成层叠上下文,除非他是根元素。
注意:z-index值为 0 与z-index值为auto的区别。区别是前者对内创建一个新的层叠上下文,后者不创建新的层叠上下文。除了这点区别,两者的层级是一样的。
In this section, the expression "in front of" means closer to the user as the user faces the screen.
在CSS 2.1中,每一个盒子处在三维空间中。除了水平轴和垂直轴外,还有一个z轴(z-axis),这三个轴共同决定了盒子在三维空间中的位置。
盒子在z轴上的位置与盒子之间的重叠关系尤其相关。
下面讨论盒子如何在z轴上定位。
每一个盒子都处在层叠上下文中。如果在给定的层叠上下文中的给每一个定位的盒子(positioned box)指定一个整数的堆叠层级,那么这个堆叠层级就是该定位盒子相对于同一层叠上下文中其他定位盒子在z轴上的位置。拥有较大堆叠层级的盒子处在拥有较小堆叠层级的盒子的前面,即距离用户更近。堆叠层级可以为负值。在同一层叠上下文中,拥有相同堆叠层级的盒子根据后来居上的规则堆叠。
产生层叠上下文的情况(不全面):
- 根元素形成根层叠上下文(the root stacking context)。
- 任何定位元素(position不为static的元素)且该元素的z-index属性不为auto。
随着CSS的不断发展,也会有新的CSS属性会引入层叠上下文,比如CSS 3中的opacity属性等。
层叠上下文与包含块不存在绝对的相关关系。
在每一个层叠上下文中,以下层次按照后来居上的规则绘制(序号越大,堆放得越靠前,距离用户越近):
Within each stacking context, the following layers are painted in back-to-front order:
- 元素的background和borders
- 拥有负堆叠层级(negative stack levels)的子层叠上下文(child stacking contexts)
- 在文档流中的(in-flow),非行内级的(non-inline-level),非定位(non-positioned)的后代元素
- 非定位的浮动元素
- 在文档流中的(in-flow),行内级的(inline-level),非定位(non-positioned)的后代元素,包括行内块级元素(inline blocks)和行内表格元素(inline tables)
- 堆叠层级为 0 的子堆叠上下文(child stacking contexts)和堆叠层级为 0 的定位的后代元素
- 堆叠层级为正的子堆叠上下文
Within each stacking context, positioned elements with stack level 0 (in layer 6), non-positioned floats (layer 4), inline blocks (layer 5), and inline tables (layer 5), are painted as if those elements themselves generated new stacking contexts, except that their positioned descendants and any would-be child stacking contexts take part in the current stacking context.
上述关于层次的绘制规则递归地适用于任何层叠上下文。
层叠上下文
MDN中列举的创建新的层叠上下文的情形
文档中的层叠上下文由满足以下任意一个条件的元素形成:
- 根元素 (HTML),
- z-index 值不为 "auto"的 绝对/相对定位,
- 一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex,
- opacity 属性值小于 1 的元素(参考 the specification for opacity),
- transform 属性值不为 "none"的元素,
- mix-blend-mode 属性值不为 "normal"的元素,
- filter值不为“none”的元素,
- perspective值不为“none”的元素,
- isolation 属性被设置为 "isolate"的元素,
- position: fixed
- 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值(参考 这篇文章)
- -webkit-overflow-scrolling 属性被设置 "touch"的元素
在层叠上下文中,其子元素同样也按照上面解释的规则进行层叠。 特别值得一提的是,其子元素的 z-index 值只在父级层叠上下文中有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。
总结:
给一个 HTML 元素定位和 z-index 赋值创建一个层叠上下文,(opacity 值不为 1 的也是相同)。
层叠上下文可以包含在其他层叠上下文中,并且一起创建一个有层级的层叠上下文。
每个层叠上下文完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
每个层叠上下文是自包含的:当元素的内容发生层叠后,整个该元素将会 在父层叠上下文中 按顺序进行层叠。
Note: 层叠上下文的层级是 HTML 元素层级的一个层级,因为只有某些元素才会创建层叠上下文。可以这样说,没有创建自己的层叠上下文的元素 将被父层叠上下文包含。
层叠上下文的层叠规则
先明确两个定义
树顺序 Tree Order
计算完元素自身的周边属性(背景颜色、背景图片、边框等)后,对渲染树进行前序深度优先遍历。
Preorder depth-first traversal of the rendering tree, in logical (not visual) order for bidirectional(双向) content, after taking into account properties that move boxes around.
元素 Element
在以下描述中,“元素”指的是实实在在的元素、伪元素以及匿名盒。伪元素和匿名盒被作为子节点(descendants)处理。
In this description, "element" refers to actual elements, pseudo-elements, and anonymous boxes. Pseudo-elements and anonymous boxes are treated as descendants in the appropriate places. For example, an outside list marker comes before an adjoining ':before' box in the line box, which comes before the content of the box, and so forth.
渲染顺序
堆叠层次的最底层距离用户最远,最上层距离用户最近,如图:
层叠上下文(也可以叫堆栈上下文)的背景和最小负数定位(z-index为负)的子层叠上下文在层叠顺序(stack)的底层,最大的正数定位的子层叠上下文在层叠顺序(stack)的顶层。
默认情况下,如果一个画布(canvas)被包含在另一个画布中,那么它将是透明的;如果它没有被包含在另一个画布中,它将被用户代理指定一个默认颜色。根元素包含在画布中,这个画布可以向外无限扩展。最初,视口(viewport)的左上角被绑定在画布的原点。
形成层叠上下文的元素的子节点(descendants)的渲染顺序(参考z-index属性):
(按照if语句嵌套的方式理解下列规则)
注意:the element是创建父级层叠上下文的元素。
从渲染树的顶层开始遍历:
1、如果the element是根元素:
- 元素的背景颜色覆盖整个画布
- 元素的背景图片覆盖整个画布,起点在画布的原点。
2、如果the element是块级元素、列表项(list-item)或其他的与块级元素同级的元素(根元素除外):
- 背景颜色
- 背景图片
- 边框
否则,如果the element是块级的表格元素:
- 表格得背景颜色,然后背景图片
- 列组(column group)的背景颜色,然后背景图片
- 列(column)的背景颜色,然后背景图片
- 行组(row group)的背景颜色,然后背景图片
- 行(row)的背景颜色,然后背景图片
- 表单元格(cell)的背景颜色,然后背景图片
- 所有的表格边框(in tree order for separated borders)
3、拥有负的z-index值的定位的子节点形成的层叠上下文,负数最小的最先渲染,然后根据树tree order渲染。
4、对于树顺序中的在文档流(in-flow),非定位,块级(block-level)子节点,如果该子节点是块级元素、列表项(list-item)或其他的与块级元素同级的元素:
- 背景颜色
- 背景图片
- 边框
否则,如果该子节点是表格元素:
- 表格得背景颜色,然后背景图片
- 列组(column group)的背景颜色,然后背景图片
- 列(column)的背景颜色,然后背景图片
- 行组(row group)的背景颜色,然后背景图片
- 行(row)的背景颜色,然后背景图片
- 表单元格(cell)的背景颜色,然后背景图片
- 所有的表格边框(in tree order for separated borders)
5、对于树顺序中所有非定位的浮动子节点,渲染这些浮动子节点时,当做他们好像也形成了一个新的层叠上下文。但是,如果是定位的子节点和确实创建了一个新的层叠上下文的子节点,那么这两种子节点还是处在父级的层叠上下文中,而不是他们创建的那个。
第6条和第7条实在翻译不下去了,还是看原文吧。
6、If the element is an inline element that generates a stacking context, then:
For each line box that the element is in:
- Jump to 7.2.1 for the box(es) of the element in that line box (in tree order).
7、Otherwise: first for the element, then for all its in-flow, non-positioned, block-level descendants in tree order:
If the element is a block-level replaced element, then: the replaced content, atomically.
Otherwise, for each line box of that element:
For each box that is a child of that element, in that line box, in tree order:
background color of element.
background image of element.
border of element.
For inline elements:
For all the element's in-flow, non-positioned, inline-level children that are in this line box, and all runs of text inside the element that is on this line box, in tree order:
If this is a run of text, then:
- any underlining affecting the text of the element, in tree order of the elements applying the underlining (such that the deepest element's underlining, if any, is painted topmost and the root element's underlining, if any, is drawn bottommost).
- any overlining affecting the text of the element, in tree order of the elements applying the overlining (such that the deepest element's overlining, if any, is painted topmost and the root element's overlining, if any, is drawn bottommost).
- the text.
- any line-through affecting the text of the element, in tree order of the elements applying the line-through (such that the deepest element's line-through, if any, is painted topmost and the root element's line-through, if any, is drawn bottommost).
Otherwise, jump to 7.2.1 for that element.
For inline-block and inline-table elements:
- For each one of these, treat the element as if it created a new stacking context, but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent stacking context, not this new one.
For inline-level replaced elements:
- the replaced content, atomically.
Some of the boxes may have been generated by line splitting or the Unicode bidirectional algorithm.
Optionally, the outline of the element (see 10 below).
Optionally, if the element is block-level, the outline of the element (see 10 below).
8、All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order. For those with 'z-index: auto', treat the element as if it created a new stacking context, but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent stacking context, not this new one. For those with 'z-index: 0', treat the stacking context generated atomically.
9、Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index order (smallest first) then tree order.
10、Finally, implementations that do not draw outlines in steps above must draw outlines from this stacking context at this stage. (It is recommended to draw outlines in this step and not in the steps above.)
参考资料:
1、z-index
2、Elaborate description of Stacking Contexts
下面看例子(没有考虑opacity),例子以根元素创建的层叠上下文为基础。
例子一
CSS代码:
div {
font: 12px Arial;
}
body{
border:1px solid white;
}
span.bold { font-weight: bold; }
.text-style{
text-align: center;
border:1px solid black;
}
#div1{
float: left;
width: 300px;
height: 50px;
background-color: pink;
text-align: right;
}
#div2{
position: absolute;
width: 280px;
height:120px;
top: 50px;
background-color: gray;
text-align: right;
}
#div3{
width: 450px;
height: 300px;
text-align: right;
margin-top: 20px;
}
#div4{
position: relative;
width: 160px;
height: 80px;
z-index:;
top:-300px;
background-color: rgb(34,200,150);
}
HTML代码:
<div id="div1" class="text-style">
<p><span class="bold">DIV #1</span>
<br />float left</p>
</div> <div id="div2" class="text-style">
<p><span class="bold">DIV #2</span>
<br />position: absolute</p>
</div> <div id="div3" class="text-style">
<p><span class="bold">DIV #3</span>
<br />no positioning, no float
</p>
</div> <div id="div4" class="text-style">
<p><span class="bold">DIV #4</span> <br />position: relative
<br /> z-index: 1
</p>
</div>
效果:

从图中可以看出,浮动元素,定位元素,常规元素,设置了z-index的元素,四种元素在同一个层叠上下文中的层叠次序一目了然。
例子二
CSS代码:
#div5{
position: absolute;
border: 1px solid black;
width:350px;
height: 300px;
z-index:;
background-color: #5555FF;
text-align: right;
}
#div6{
position: absolute;
border: 1px solid black;
width:250px;
height: 200px;
z-index: auto;
background-color: #FFBB66;
text-align: right;
}
#div7{
position: absolute;
border: 1px solid black;
width:450px;
height: 180px;
z-index: -1;
background-color: #66FF66;
text-align: right;
}
#div8{
position: relative;
border: 1px solid black;
width:150px;
height: 250px;
z-index:;
background-color: #E38EFF;
}
HTML代码:
<div id="div5" class="text-style">
<p><span class="bold">DIV #5</span>
<br />position: absolute
<br /> z-index: 0
</p>
</div> <div id="div6" class="text-style">
<p><span class="bold">DIV #6</span>
<br />position: absolute
<br /> z-index: auto
</p>
</div> <div id="div7" class="text-style">
<p><span class="bold">DIV #7</span>
<br />position: absolute
<br /> z-index: -1
</p>
</div> <div id="div8" class="text-style">
<p><span class="bold">DIV #8</span>
<br />position: relative
<br /> z-index: 1
</p>
</div>
效果:

CSS——关于z-index及层叠上下文(stacking context)的更多相关文章
- 层叠上下文 Stacking Context
层叠上下文 Stacking Context 在CSS2.1规范中,每个盒模型的位置是三维的,分别是平面画布上的x轴,y轴以及表示层叠的z轴.对于每个html元素,都可以通过设置z-index属性来设 ...
- 彻底搞懂CSS层叠上下文、层叠等级、层叠顺序、z-index
前言 最近,在项目中遇到一个关于CSS中元素z-index属性的问题,具体问题不太好描述,总结起来就是当给元素和父元素色设置position属性和z-index相关属性后,页面上渲染的元素层级结果和我 ...
- 带大家认识CSS层叠上下文/层叠等级的区别和意义
什么是“层叠上下文” 层叠上下文(stacking context),是HTML中一个三维的概念.在CSS2.1规范中,每个盒模型的位置是三维的,分别是平面画布上的X轴,Y轴以及表示层叠的Z轴.一般情 ...
- css--深入理解z-index引发的层叠上下文、层叠等级和层叠顺序
前言 在编写css样式代码的时候,我们经常会遇到z-index属性的使用,我们可能只了解z-index能够提高元素的层级,并不知道具体是怎么实现的.本文就来总结一个由z-index 引发的层叠上下文和 ...
- 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 层叠上下文(The stacking context)
MDNThe stacking context 层叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的z轴上延伸,HTML元素依据其自身属性按照优 ...
- 一篇通俗易懂的CSS层叠顺序与层叠上下文研究
网上有很多这方面的教程,但不是苦涩难懂就是从哪copy过来的,反正很长一段时间我是没看懂,时间长了也没打算去研究了,主要原因是,基本上很少会遇到那些问题(所以说啊,要是没有研究精神的才懒得管它).但自 ...
- CSS基础:层叠顺序和层叠上下文
简介 在考虑到两个元素可能重叠的情况下,层叠顺序决定了那个元素在前面,那个元素在后面,这是针对普通元素而言.而层叠上下文和块级格式化上下文 (BFC) 一样,基本上也是由一些 CSS 属性创建的,它单 ...
- CSS 的层叠上下文是什么
层叠上下文是 HTML 中的一个三维的概念,每个层叠上下文中都有一套元素的层叠排列顺序.页面根元素天生具有层叠上下文,所以整个页面处于一个“层叠结界”中. 层叠上下文的创建: 页面根元素:html z ...
随机推荐
- 应用工具 .NET Portability Analyzer 分析迁移dotnet core
大多数开发人员更喜欢一次性编写好业务逻辑代码,以后再重用这些代码.与构建不同的应用以面向多个平台相比,这种方法更加容易.如果您创建与 .NET Core 兼容的.NET 标准库,那么现在比以往任何时候 ...
- 3.Windows Server 2012 R2数据库部署
很多人竟然不会安装数据库....好吧,来个图文教程,其实和windows里面一样安装,和安装2008一样的 先安装3.5:http://www.cnblogs.com/dunitian/p/53487 ...
- AES加密
package com.edu.hpu; import java.math.BigInteger; import java.security.MessageDigest; import java.se ...
- ASP.NET Core的路由[4]:来认识一下实现路由的RouterMiddleware中间件
虽然ASP.NET Core应用的路由是通过RouterMiddleware这个中间件来完成的,但是具体的路由解析功能都落在指定的Router对象上,不过我们依然有必要以代码实现的角度来介绍一下这个中 ...
- SDWebImage源码解读 之 NSData+ImageContentType
第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...
- ES6的一些常用特性
由于公司的前端业务全部基于ES6开发,于是给自己开个小灶补补ES6的一些常用特性.原来打算花两天学习ES6的,结果花了3天才勉强过了一遍阮老师的ES6标准入门(水好深,ES6没学好ES7又来了...) ...
- Hibernate中事务的隔离级别设置
Hibernate中事务的隔离级别,如下方法分别为1/2/4/8. 在Hibernate配置文件中设置,设置代码如下
- 排序算法----调用库函数qsort进行快速排序
功 能: 快速排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const ...
- 当前端也拥有 Server 的能力
今天看了不少文章,比较感兴趣的是 Cache API.它是浏览器 Request/Response 的缓存管理工具,其使用风格和运用场景让我瞬间联想到了 ServiceWorker 和 Fetch A ...
- ASP.NET Web API Selfhost宿主环境中管道、路由
ASP.NET Web API Selfhost宿主环境中管道.路由 前言 前面的几个篇幅对Web API中的路由和管道进行了简单的介绍并没有详细的去说明一些什么,然而ASP.NET Web API这 ...