澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

index堆成堆法则,中的层叠上下文初探

2019-09-11 作者:澳门新萄京赌场网址   |   浏览(164)

CSS3 中的层叠上下文初探

2015/10/09 · CSS · 层叠上下文

原文出处: HaoyCn   

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

深入CSS属性(九):z-index,深入css属性z-index

如果你不是一名csser新手,想必你对z-index的用法应该有个大致的了解了吧,z-index可以控制定位元素在垂直于显示屏方向(Z 轴)上的堆叠顺序,本文不去讲述基本的API如何使用,而是去更深入的了解z-index是如何工作的,使用z-index的时候有哪些问题,以及z-index在日常开发中的使用。 下面我们通过一个例子来引入今天的正文,代码示例:

<style type="text/css">
 .red, .green, .blue {
  position: absolute;
  width: 100px;
  height: 100px;
  text-align: center;
  line-height: 100px;
  color: #fff;
 }
 .red {
  background-color: red;
  z-index: 1;
 }
 .green {
  background-color: green;
  top: 70px;
  left: 70px;
 }
 .blue {
  background-color: blue;
  top: 140px;
  left: 140px;
 }
</style>  
<div>
 Red box
</div>
<div>
 Green box
</div>
<div>
 Blue box
</div>

如下图: 澳门新萄京官方网站 1

上述代码通俗易懂,下面有个问题请大家思考: 在遵循下述规则的情况下,如何使用红色span元素在green和blue元素后面?

1) 不能以任何方式更改html标记;

2) 不能增加或改变任何元素的z-index属性;

3) 不恩增加或改变任何元素的position属性;

请大家思考,这个问题改如何解决?说明其原因?

z-index堆叠规则,z-index堆叠

层叠上下文 Stacking Context

2015/09/02 · CSS · 层叠上下文

原文出处: elcarim的博客   

在CSS2.1规范中,每个盒模型的位置是三维的,分别是平面画布上的x轴,y轴以及表示层叠的z轴。对于每个html元素,都可以通过设置z-index属性来设置该元素在视觉渲染模型中的层叠顺序。

z-index可以设置成三个值:

  • auto,默认值。当设置为auto的时候,当前元素的层叠级数是0,同时这个盒不会创建新的层级上下文(除非是根元素,即<html>);
  • <integer>。指示层叠级数,可以使负值,同时无论是什么值,都会创建一个新的层叠上下文;
  • inherit

除了由根根元素创建的根层叠上下文以外,其它上下文是由z-index不为auto的“positioned”元素所创建。

参考层叠级数,浏览器会根据以下规则来渲染绘制每个在同一个层叠上下文中的盒模型:
(从先绘制到后绘制)

  1. 创建层叠上下文的元素的背景和边界;
  2. z-index为负值的子元素,数值越小越早被绘制;
  3. 同时满足“in-flow”、“non-inline-level”、“non-positioned”的后代元素;
  4. “non-positioned”的浮动元素
  5. 满足“in-flow”、“inline-level”、“non-positioned”的后代元素;
  6. 层叠级数为0的子层叠上下文以及“positioned”且层叠级数为0的后代元素;
  7. 层叠级数大于等于1的“positioned”子层叠上下文,数值越小越早被绘制;

在规则中,提到了几种元素的修饰词,下面是简单的解释:

  • “positioned”指的是positionfixedabsoluterelative;那么如果未设置或为static的就是“non-positioned”元素;
  • “out-of-flow”元素指的浮动的或绝对定位(fixedabsolute)的元素,又或者是根元素;如果不是上述情况,那个这个元素就是“in-flow”
  • “inline-level”元素指的是displayinlineinline-tableinline-block的元素;

规则有点多,但简单说,就是父元素会先绘制,接着是z-index为负值的子元素,然后是“non-positioned”元素,最后是按照层叠级数从0开始逐级绘制(这样说比较简单,省略了大量细节,因此并不是很准确)。如果层级相同,则按照元素在DOM树中的顺序来进行绘制。

从这样看,要让z-index非负的元素按照层级控制生效,那么就将该元素设置为“positioned”,这也是许多文章中普遍提到的规则。

下面,将利用MDN中的例子来分析和解释层叠上下文中的规则和计算方法,部分代码使用的MDN上的源码,另外一些是经过细微修改,目的是为了更好得把问题描述得更清楚。

1 CSS2.1 中规定的层叠上下文澳门新萄京官方网站 2

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.

图文来源:http://webdesign.tutsplus.com/articles/what-you-may-not-know-about-the-z-index-property–webdesign-16892

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

  • 背景和边框:建立层叠上下文元素的背景和边框。层叠中的最低级
  • 负 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 新环境下,层叠上下文的新变化。

----------------------------------- 分割线

一、z-index

z-index用来控制元素重叠时堆叠顺序。

适用于:已经定位的元素(即position:relative/absolute/fixed)。

一般理解就是数值越高越靠上,好像很简单,但是当z-index应用于复杂的HTML元素层次结构,其行为可能很难理解甚至不可预测。因为z-index的堆叠规则很复杂,下面一一道来。

首先解释一个名词:

stacking context:翻译就是“堆叠上下文”。每个元素仅属于一个堆叠上下文,元素的z-index描述元素在相同堆叠上下文中“z轴”的呈现顺序。

z-index取值:

默认值auto:

当页面新生成一个box时,它默认的z-index值为auto,意味着该box不会自己产生一个新的local stacking context,而是处于和父box相同的堆叠上下文中。

正/负整数

这个整数就是当前box的z-index值。z-index值为0也会生成一个local stacking context,这样该box父box的z-index就不会和其子box做比较,相当于隔离了父box的z-index和子box的z-index。

接下来从最简单的不使用z-index的情况开始将,循序渐进。

不设置z-index的层叠

利用MDN上的一个例子来说明。

为了方便比较,将源码简化成如下:

XHTML

<body> <div id="absdiv1">DIV #1</div> <div id="reldiv1">DIV #2</div> <div id="reldiv2">DIV #3</div> <div id="absdiv2">DIV #4</div> <div id="normdiv">DIV #5</div> </body>

1
2
3
4
5
6
7
<body>
<div id="absdiv1">DIV #1</div>
<div id="reldiv1">DIV #2</div>
<div id="reldiv2">DIV #3</div>
<div id="absdiv2">DIV #4</div>
<div id="normdiv">DIV #5</div>
</body>

其中DIV#1DIV#4是粉色框,position设置为absolute

DIV#2DIV#3是粉色框,position设置为relative

DIV#5是黄色框,position为设置,默认static

澳门新萄京官方网站 3

根据规则,由于DIV#5是“non-positioned”,即使DIV#5是DOM树中最后的元素,它也是最早被绘制的,因此它处于所有“positioned”的下面;而对于其余四个“positioned”的DIV,它们的绘制顺序就是按照在DOM树中的顺序绘制,即DIV#1->DIV#2->DIV#3->DIV#4

尽管DIV#5是最“先绘制”的,但是浏览器在解析HTML的时候仍然是按照HTML文档流的顺序来解析的,实际的绘制顺序仍然是DIV#1->DIV#2->DIV#3->DIV#4->DIV#5。只不过,要绘DIV#5的时候,会对影响到的元素进行重新绘制,其渲染的效果看上去的顺序是DIV#5->DIV#1->DIV#2->DIV#3->DIV#4,将DIV#5提到了最前。

2 CSS3 带来的变化

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

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

一、z-index 黄金法则及stack context

1) 一个box和它的父亲有相同的堆叠级别(stack level),除非该box被通过z-index属性赋予了不同的stack level;

2) z-index属性只适应于position属性为relative、absolute、fixed的元素对象;

3) 给一个被定位(positioned)元素设置小于1的opacity属性值,意味着创建了一个堆叠上下文(stack context),就像给该元素增加了一个z-index值;

4) 对于一个被positioned box,如果指定了z-index属性,意味着:

->该box的stack level 在当前的stack context中;

->该box建立了个本地stack context;

5) 如果box没有指定z-index,元素将被按下面的顺序堆叠(stacked)(从后到前):

-> 正常流中的boxes,根据在源代码中的序列;

-> 浮动boxes;

-> computed后display属性值为inline/inline-block/inline-table的boxes;

-> positioned boxes 和boxes 设置opacity值小于1,根据在源代码中的序列;

 

 

因此,当我们给一个positioned元素设置了z-index时,我们做了两件事:

1) 该元素与在它前面或者后面的元素共享着相同的stack context,这也就是我们改变z-index的值,元素会移动其他元素前后者后的原因。

2) 为该元素内的任何元素创建了一个新的stack context,一旦你创建了一个stack context,内部的任何有(stack context)的任何层都会停留在这个stack context。 通过上述的黄金法则,也许你已经知道上面那个问题的答案了。在黄金法则里,我们提到了个新名词“stack context”,下面我们通过一个实例来介绍它:

<!DOCTYPE html>
<html>
<html lang="en">
<head>
 <meta charset="utf-8">
 <title>z-index example</title>
</head>
<body>
<h1>Header</h1>  
<p>I am paragraph. <em> I am em</em></p>   
</body>
</html>

一个很特殊的情况是,在一个document中,没有任何定位,document有且只有一个堆叠环境

  • 通过HTML创建。 下面我们给上例添加如下样式:

    h1, p {
     position: relative;
    } 
    h1 {
     z-index: 2;
    }
    p {
     z-index: 1;
    }
    

在这种情况下,h1,p都创建了一个stack context,这两个stack context都在document的stack context内。增加样式后h1在p元素之上。如果我们给em元素增加如下样式结果又会怎样:

  h1, p, em {
   position: relative;
  } 
  h1 {
   z-index: 2;
   background-color: #f0f;
  }
  p {
   z-index: 1;
   background-color: #00f;
   line-height: 40px;
  }
  em {
   z-index: 1;
   background-color: #f00;
  }

增加此样式后em创建了stack context,由于em的z-index属性,它的内部的text比p标签中的其它text更接近用户。因为它是在p的stack context内部,它是一直比h1中的text低的。 注意:如果你增加z-index的值,是不能使用em位于h1之上的。如果你想一个context的元素位于另一个context中的元素之上,你必须提升整个context或者设置它们为相同的context。 下面是两种解决方案: 方案一:

  h1, p, em {
   position: relative;
  } 
  h1 {
   z-index: 2;
   background-color: #f0f;
  }
  p {
   /* raise the entire context,p and em 都在h1 之上了*/
   z-index: 3;
   background-color: #00f;
   line-height: 40px;
   margin-top: -40px;
  }
  em {
   z-index: 1;
   background-color: #f00;
  }

方案二:

  h1, p, em {
   position: relative;
  } 
  h1 {
   z-index: 2;
   background-color: #f0f;
  }
  p {
   background-color: #00f;
   line-height: 40px;
   margin-top: -40px;
  }
  em {
   /*  put them into the same context */
   z-index: 2;
   background-color: #f00;
  }

二、不使用 z-index时堆叠顺序

不使用z-index的情况,也是默认的情况,即所有元素都不用z-index时,堆叠顺序如下(从下到上)

  • 根元素(即HTML元素)的background和borders
  • 正常流中非定位后代元素(这些元素顺序按照HTML文档出现顺序)
  • 已定位后代元素(这些元素顺序按照HTML文档出现顺序)

解释一下后两条规则:

  • 正常流中非positoned element元素,总是先于positioned element元素渲染,所以表现就是在positioned element下方,跟它在HTML中出现的顺序无关。
  • 没有指定z-index值的positioned element,他们的堆叠顺序取决于在HTML文档中的顺序,越靠后出现的元素,位置越高,和position属性无关。

例子:

澳门新萄京官方网站 4<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Stacking without z-index</title> <style type="text/css"> div { font: 12px Arial; text-align: center; } .bold { font-weight: bold; } .opacity{opacity: 0.7;} #normdiv { height: 70px; border: 1px dashed #999966; background-color: #ffffcc; margin: 0px 50px 0px 50px; } #reldiv1 { height: 100px; position: relative; top: 30px; border: 1px dashed #669966; background-color: #ccffcc; margin: 0px 50px 0px 50px; } #reldiv2 { height: 100px; position: relative; top: 15px; left: 20px; border: 1px dashed #669966; background-color: #ccffcc; margin: 0px 50px 0px 50px; } #absdiv1 { position: absolute; width: 150px; height: 350px; top: 10px; left: 10px; border: 1px dashed #990000; background-color: #ffdddd; } #absdiv2 { position: absolute; width: 150px; height: 350px; top: 10px; right: 10px; border: 1px dashed #990000; background-color: #ffdddd; } </style> </head> <body> <br /><br /> <div id="absdiv1" class="opacity"> <br /><span class="bold">DIV #1</span> <br />position: absolute; </div> <div id="reldiv1" class="opacity"> <br /><span class="bold">DIV #2</span> <br />position: relative; </div> <div id="reldiv2" class="opacity"> <br /><span class="bold">DIV #3</span> <br />position: relative; </div> <div id="absdiv2" class="opacity"> <br /><span class="bold">DIV #4</span> <br />position: absolute; </div> <div id="normdiv"> <br /><span class="bold">DIV #5</span> <br />no positioning </div> </body> </html> View Code

有图有真相:

澳门新萄京官方网站 5

 分析:

#5没有定位,处于正常流,所以根据以上规则,先于#1,#2,#3,#4这些已定位元素渲染,在最下方。

#1,#2,#3,#4都是已定位元素,且未设置z-index,所以根据其在文档中出现的顺序依次被渲染,可以去掉apacity查看清晰效果。

float的层叠

同样是要MDN上面的例子来说明。

JavaScript

<body> <div id="absdiv1"> <br /><span class="bold">DIV #1</span> <br />position: absolute; </div> <div id="flodiv1"> <br /><span class="bold">DIV #2</span> <br />float: left; </div> <div id="flodiv2"> <br /><span class="bold">DIV #3</span> <br />float: right; </div> <br /> <div id="normdiv"> <br /><span class="bold">DIV #4</span> <br />no positioning </div> <div id="absdiv2"> <br /><span class="bold">DIV #5</span> <br />position: absolute; </div> </body>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<body>
<div id="absdiv1">
        <br /><span class="bold">DIV #1</span>
        <br />position: absolute;
    </div>
 
    <div id="flodiv1">
        <br /><span class="bold">DIV #2</span>
        <br />float: left;
    </div>
 
    <div id="flodiv2">
        <br /><span class="bold">DIV #3</span>
        <br />float: right;
    </div>
 
    <br />
 
    <div id="normdiv">
        <br /><span class="bold">DIV #4</span>
        <br />no positioning
    </div>
 
    <div id="absdiv2">
        <br /><span class="bold">DIV #5</span>
        <br />position: absolute;
    </div>
</body>

 

其中DIV#1DIV#5是粉色框,position设置为absolute

DIV#1DIV#2是粉色框,float设置分别为leftrightopacity是1;

DIV#4是黄色框,position为设置,默认static

澳门新萄京官方网站 6

上一节的例子类似,由于DIV#4是“non-positioned”,所以DIV#4仍然是最先绘制的,因此它的背景和边界将在所有元素的最下面。而且根据规则,DIV#4中的inline-level元素()会在浮动元素绘制以后才绘制,结果是被挤到了DIV#2的右边。

根据规则,浮动元素是在“positioned”元素之前绘制,因此DIV#1DIV#5会在两个浮动元素的上面。

要注意到,在这里几个<div>的并没有设置透明度,这跟MDN上的源码有所区别。那现在,如果完全按照MDN的源码,将DIV#1DIV#2DIV#3DIV#5opacity设置为0.7,显示结果如下:

澳门新萄京官方网站 7

仔细观察,可以发现,在设置了opacity后,DIV#3的层级被提高到了DIV#1之上了。这与CSS2.1上的规定有所区别。

如果对DIV#4设置opacity:0.99,结果更加出人意料:

澳门新萄京官方网站 8

原本在最下面的DIV#4跑到了更加前面的位置,只位于DIV#5之下。

由于opacity并不是在CSS2.1里规定,需要使用CSS3中新的规则来解释这一个现象,更容易理解z-index的规则,现在暂时不讨论opacity所带来的影响,避免把规则变得更复杂。

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

以上列表译自:

,提醒广大读者,别看中文版,因为中文版并非实时跟进更新的,且翻译不太准确

二、创建stack context及注意事项

那么创建stack context的方式有哪些?

1) When an element is the root element of a document (theelement)

2) When an element has a position value other than static and a z-index value other than auto

3) When an element has an opacity value less than 1

Update: In addition to opacity, several newer CSS properties also create stacking contexts. These include: transforms, filters, css-regions, paged media, and possibly others. As a general rule, it seems that if a CSS property requires rendering in an offscreen context, it must create a new stacking context.

 

In WebKit, styling a box with position:fixed or -webkit-overflow-scrolling:touch implicitly creates a stacking context, just like adding a z-index value.

Also, be aware of these CSS3 “triggers”:

transform != none

transform-style: preserve-3d

filter != none clip-path, mask

Lastly, even though a relatively positioned element without a z-index set does not establish a stacking context… A common IE bug, often seen in drop-down menus, is that any relatively positioned element that has haslayout set to true establishes a stacking context. One may visualize this bug by setting [A] and [B] to position:relative, while [a] gets position:relative; z-index:1. Now, dragging [A] under [B] hides [a] - in Internet Explorer, that is. Any positioned child with a z-index is caught by this wrong stacking context of its parent.

三、浮动堆叠顺序

浮动元素z-index位置介于非定位元素和定位元素之间。(从下到上)

  • 根元素(即HTML元素)的背景和border
  • 正常流中非定位后代元素(这些元素顺序按照HTML文档出现顺序)
  • index堆成堆法则,中的层叠上下文初探。浮动元素(浮动元素之间是不会出现z-index重叠的)
  • 正常流中inline后代元素
  • 已定位后代元素(这些元素顺序按照HTML文档出现顺序)

 non-positioned元素的背景和边界没有被浮动元素影响,但是元素中的内容受影响(浮动布局特性)

举例:

澳门新萄京官方网站 9<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Stacking and float</title> <style type="text/css"> div { font: 12px Arial; text-align: center; } .bold { font-weight: bold; } .opacity{ opacity: 0.7;} #absdiv1 { position: absolute; width: 150px; height: 200px; top: 10px; right: 140px; border: 1px dashed #990000; background-color: #ffdddd; } #index堆成堆法则,中的层叠上下文初探。normdiv { /* opacity: 0.7; */ height: 100px; border: 1px dashed #999966; background-color: #ffffcc; margin: 0px 10px 0px 10px; text-align: left; } #flodiv1 { margin: 0px 10px 0px 20px; float: left; width: 150px; height: 200px; border: 1px dashed #009900; background-color: #ccffcc; } #flodiv2 { margin: 0px 20px 0px 10px; float: right; width: 150px; height: 200px; border: 1px dashed #009900; background-color: #ccffcc; } #absdiv2 { position: absolute; width: 150px; height: 100px; top: 130px; left: 100px; border: 1px dashed #990000; background-color: #ffdddd; } </style> </head> <body> <br /><br /> <div id="absdiv1" class="opacity"> <br /><span class="bold">DIV #1</span> <br />position: absolute; </div> <div id="flodiv1" class="opacity"> <br /><span class="bold">DIV #2</span> <br />float: left; </div> <div id="flodiv2" class="opacity"> <br /><span class="bold">DIV #3</span> <br />float: right; </div> <br /> <div id="normdiv"> <br /><span class="bold">DIV #4</span> <br />no positioning </div> <div id="absdiv2" class="opacity"> <br /><span class="bold">DIV #5</span> <br />position: absolute; </div> </body> </html> View Code

澳门新萄京官方网站 10

分析:

#4是正常流中非定位的元素,所以先被渲染,在最底层。

#2 #3一个左浮动,一个右浮动,接着被渲染。彼此不会因为z-index值被覆盖。见下图。

#1 #5为已定位的元素,最后被渲染,当浏览器窗口变小时,#5在#1上面,因为HTML文档中#5在#1后面。见下图。

 澳门新萄京官方网站 11

设置了z-index的层叠

再次使用MDN中的例子:

XHTML

<body> <div id="absdiv1">DIV #1</div> <div id="reldiv1">DIV #2</div> <div id="reldiv2">DIV #3</div> <div id="absdiv2">DIV #4</div> <div id="normdiv">DIV #5</div> </div>

1
2
3
4
5
6
7
<body>
    <div id="absdiv1">DIV #1</div>
    <div id="reldiv1">DIV #2</div>
    <div id="reldiv2">DIV #3</div>
    <div id="absdiv2">DIV #4</div>
    <div id="normdiv">DIV #5</div>
</div>

 

为了让结构更加清楚,简化了HTML源码,下面是每个<div>的属性设置:

  • DIV#1position: absolutez-index: 5
  • DIV#2position: relativez-index: 3
  • DIV#3position: relativez-index: 2
  • DIV#4position: absolutez-index: 1
  • DIV#5position: staticz-index: 8
  • 澳门新萄京官方网站 12
  • 又见到了可怜的DIV#5,尽管它的z-index:8是所有元素中最大的,但由于它是“non-posititoned”所以,它在层叠上还是地位低下,仍然要老老实实呆在其他元素的下面。

    而对于其他“positioned”元素,它们的绘制顺序就是按照z-index的大小来加以分别,因此尽管DIV#1在DOM树中是最靠前的,但由于它的z-index: 5比其他都大,因此就成了最顶层的元素了。

    层叠上下文

    首先,回忆一下,创造层叠上下文的两种情况:

    • 根元素,创建根层叠上下文;
    • z-index不为autopositioned元素;

    ### 实例一(同一层叠上下文中的时代)

    继续使用MDN上的例子,来说明如果层叠上下文对z-index计算的影响。

XHTML

&lt;body&gt; &lt;div id="div1"&gt; &lt;div id="div2"&gt;&lt;/div&gt;
&lt;/div&gt; &lt;div id="div3"&gt; &lt;div id="div4"&gt;&lt;/div&gt;
&lt;/div&gt; &lt;/body&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6938563cb085489625-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6938563cb085489625-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6938563cb085489625-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6938563cb085489625-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6938563cb085489625-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6938563cb085489625-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f6938563cb085489625-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6938563cb085489625-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f6938563cb085489625-9">
9
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6938563cb085489625-1" class="crayon-line">
&lt;body&gt;
</div>
<div id="crayon-5b8f6938563cb085489625-2" class="crayon-line crayon-striped-line">
 &lt;div id=&quot;div1&quot;&gt;
</div>
<div id="crayon-5b8f6938563cb085489625-3" class="crayon-line">
    &lt;div id=&quot;div2&quot;&gt;&lt;/div&gt;
</div>
<div id="crayon-5b8f6938563cb085489625-4" class="crayon-line crayon-striped-line">
 &lt;/div&gt;
</div>
<div id="crayon-5b8f6938563cb085489625-5" class="crayon-line">
 
</div>
<div id="crayon-5b8f6938563cb085489625-6" class="crayon-line crayon-striped-line">
 &lt;div id=&quot;div3&quot;&gt;
</div>
<div id="crayon-5b8f6938563cb085489625-7" class="crayon-line">
    &lt;div id=&quot;div4&quot;&gt;&lt;/div&gt;
</div>
<div id="crayon-5b8f6938563cb085489625-8" class="crayon-line crayon-striped-line">
 &lt;/div&gt;
</div>
<div id="crayon-5b8f6938563cb085489625-9" class="crayon-line">
&lt;/body&gt;
</div>
</div></td>
</tr>
</tbody>
</table>

免去其他杂乱的样式和显示,HTML的主体结构如上所示,其中的属性设置如下:

-   `DIV#1`:`position: relative`;
    -   `DIV#2`:`position: absolute`, `z-index: 1`;
-   `DIV#3`:`position: relative`;
    -   `DIV#4`:`posititon: absolute`;

从代码就可以推断出,除了根元素创建的根层叠上下文以外,还有`DIV#2`所创建的层叠上下文。因此,尽管`DIV#2`与`DIV#3`或`DIV#4`都不在一个BFC(块格式化上下文)中,但它们都同处于一个层叠上下文中,因此根据层叠规则,`DIV#2`的`z-index`最高,因此处于另外三个元素之上。

显示的结果则如下图:

澳门新萄京官方网站 13

 

当然,如果将DIV#4设置z-index: 2,那么DIV#4就会跑到最顶部:

澳门新萄京官方网站 14

从此可以得知,层叠计算时,将考虑同一个层叠上下文中的所有元素而不考虑元素是否有其他联系。

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: 0 且 opacity: 1 的情况中的层叠顺序绘制。如果 opacity 小于 1 且已定位,z-index 属性按 CSS2.1 应用,但 auto 要视为 0,因为新的层叠上下文总是创建了的。

如下案例:

CSS

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>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 规则:

CSS

#box2 { opacity: .5; }

1
2
3
#box2 {
    opacity: .5;
}

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

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

CSS

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

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

三、z-index在某些浏览器中的问题

1) IE6中的 select元素是一个窗口控件,所以它总是出现在层叠顺序的顶部而不会顾及到自然层叠顺序、position属性或者是z-index。可以在div元素上添加一个iframe设置为position:absolute,并设置div的z-index比iframe的高。

2) 因父容器(元素)被定位的缘故,IE6/7会错误的对其stacking context进行重置。

3) 在Firefox2版本中,一个负的z-index值会使元素位于stacking context的后面,而不是位于公认的背景和边框这样的元素stacking context之前。 本文到此结束,最后附上本文开始时提出的问题的答案:

/* add this */
div:first-child {
opacity: .99;
}

感谢您的阅读,文中不妥之处,还望批评指正。

四、z-index

默认的堆叠顺序上面说了,要想改变 元素的堆叠顺序就得用到z-index。

Note:前两种情况中,虽然有元素之间的重叠覆盖,但是它们都是处在同一个z-layer的。因为没有设置z-index属性,默认的渲染层就是layer 0。所以要注意,不同层中元素之间覆盖是理所当然的,但是同一层中的元素也会发送覆盖。

z-index只适用于已经定位的元素(即position:relative/absolute/fixed)。

举例:

澳门新萄京官方网站 15<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Stacking without z-index</title> <style type="text/css"> div { font: 12px Arial; text-align: center; opacity: 0.7; } .bold { font-weight: bold; } #normdiv { z-index: 8; height: 70px; border: 1px dashed #999966; background-color: #ffffcc; margin: 0px 50px 0px 50px; } #reldiv1 { z-index: 3; height: 100px; position: relative; top: 30px; border: 1px dashed #669966; background-color: #ccffcc; margin: 0px 50px 0px 50px; } #reldiv2 { z-index: 2; height: 100px; position: relative; top: 15px; left: 20px; border: 1px dashed #669966; background-color: #ccffcc; margin: 0px 50px 0px 50px; } #absdiv1 { z-index: 5; position: absolute; width: 150px; height: 350px; top: 10px; left: 10px; border: 1px dashed #990000; background-color: #ffdddd; } #absdiv2 { z-index: 1; position: absolute; width: 150px; height: 350px; top: 10px; right: 10px; border: 1px dashed #990000; background-color: #ffdddd; } </style> </head> <body> <br /><br /> <div id="absdiv1"> <br /><span class="bold">DIV #1</span> <br />position: absolute; <br />z-index: 5; </div> <div id="reldiv1"> <br /><span class="bold">DIV #2</span> <br />position: relative; <br />z-index: 3; </div> <div id="reldiv2"> <br /><span class="bold">DIV #3</span> <br />position: relative; <br />z-index: 2; </div> <div id="absdiv2"> <br /><span class="bold">DIV #4</span> <br />position: absolute; <br />z-index: 1; </div> <div id="normdiv"> <br /><span class="bold">DIV #5</span> <br />no positioning <br />z-index: 8; </div> </body> </html> View Code

澳门新萄京官方网站 16

实例二(拼爹的时代)

依然上上面的例子:

XHTML

<body> <div id="div1"> <div id="div2"></div> </div> <div id="div3"> <div id="div4"></div> </div> </body>

1
2
3
4
5
6
7
8
9
<body>
<div id="div1">
   <div id="div2"></div>
</div>
 
<div id="div3">
   <div id="div4"></div>
</div>
</body>

 

但现在将各个元素的属性做一些修改:

  • DIV#1position: relative
    • DIV#2position: absolute, z-index: 2
  • DIV#3position: relativez-index: 1
    • DIV#4posititon: absolutez-index: 100

在看结果之前,先根据源码推断一下计算的结果。首先,DIV#2创建了一个层叠上下文(SC2),而DIV#2本身在根层叠上下文中的层级是2;与DIV#2处于同一个层叠上下文的DIV#3也创建了一个层叠上下文(SC3),同时由于其z-index1,比DIV#2要小,DIV#3理所当然地会屈于DIV#2之下;另外,DIV#3还有一个子元素DIV#4DIV#4显然是处于DIV#3所创建的层叠上下文(SC3)中,同时,自己又创建了另一个新的层级上下文(SC4)。

那么问题来了,DIV#4z-index100,比所有元素都要大,那么DIV#4会处于什么位置呢?

澳门新萄京官方网站 17

从结果可以看到,DIV#2DIV#3位置和预想中是一样的,但由于DIV#4则是处于DIV#2之下DIV#3之上。其中原因还,DIV#4所处的层叠上下文SC3的层级比SC2要低,因此不管DIV#4有多大,它都不会超过比自身高的层叠上下文中的元素

如果改一改各个元素的属性:

  • DIV#1position: relativez-index: 1
    • DIV#2position: absolute, z-index: 100
  • DIV#3position: relativez-index: 1
    • DIV#4posititon: absolutez-index: 2

澳门新萄京官方网站,通过修改代码,我们让DIV#1DIV#3z-index1,它们在SC0(根层叠上下文)中的层级都是1,那么它们将按照DOM树的顺序来绘制,这意味着DIV#3稍微比DIV#1高那么一点。

在这两个层叠上下文中,分别有子元素DIV#2DIV#4。此时,尽管DIV#2的层级数非常大,但由于它所处的层叠上下文SC1在SC3之下,因此DIV#2不仅在DIV#4之下,还会位于DIV#3之下。显示结果如下图所示:

澳门新萄京官方网站 18

通过这个例子,可以更清楚得认识到,层叠的计算是非常依赖所处的层叠上下文的,用刚通俗的话讲,层叠计算时期是一个拼爹的时代。

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

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

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

固定定位元素

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

CSS

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>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 将会铺满整个屏幕。

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

CSS

#transform { transform: scale(1); }

1
2
3
#transform {
    transform: scale(1);
}

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

绝对定位元素

我们举一个例子:

CSS

#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>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#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。然后我们添加如下规则:

CSS

#transform { transform: scale(1); }

1
2
3
#transform {
    transform: scale(1);
}

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

1 赞 1 收藏 评论

澳门新萄京官方网站 19

四、参考链接:

Find out how elements stack and start using low z-index values

The Z-Index CSS Property: A Comprehensive Look

Elaborate description of Stacking Contexts

Overlapping And ZIndex

CSS/Properties/z-index

Understanding CSS z-index(MDN)

What No One Told You About Z-Index

测试Demo:

 

原载于: Benjamin 
本文链接:  
如需转载请以链接形式注明原载或原文地址。

五、stacking context

为什么上个例子中元素的堆叠顺序受z-index的影响呢?因为这些元素有些特殊的属性触发它们生存堆叠上下文(stacking context)。

问题来了,什么样的元素会生成堆叠上下文呢?符合下面规则之一的:

  • 根元素(即HTML元素)
  • 已定位元素(即绝对定位或相对定位)并且z-index不是默认的auto。
  • a flex item with a z-index value other than "auto",
  • 元素opacity属性不为1(See the specification for opacity)
  • 元素transform不为none
  • 元素min-blend-mode不为normal
  • 元素filter属性不为none
  • 元素isolation属性为isolate
  • on mobile WebKit and Chrome 22 , position: fixed always creates a new stacking context, even when z-index is "auto" (See this post)
  • specifing any attribute above in will-change even you don't write themselves directly (See this post)
  • elements with -webkit-overflow-scrolling set to "touch"

在堆叠上下文(stacking context)中 ,子元素的堆叠顺序还是按照上述规则。重点是,子元素的z-index值只在父元素范围内有效。子堆叠上下文被看做是父堆叠上下文中一个独立的模块,相邻的堆叠上下文完全没关系。

总结几句:

渲染的时候,先确定小的stacking context中的顺序,一个小的stacking context确定了以后再将其放在父stacking context中堆叠。有种由内而外,由小及大的感觉。

举例:HTML结果如下,最外层是HTML元素,包含#1 #2 #3,#3中又包含着#4,#5,#6。

Root(HTML)

  • DIV #1
  • DIV #2
  • DIV #3
    • DIV #4
    • DIV #5
    • DIV #6

澳门新萄京官方网站 20<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "; <html xmlns="" xml:lang="en"> <head> <title>Understanding CSS z-index: The Stacking Context: Example Source</title> <style type="text/css"> * { margin: 0; } html { padding: 20px; font: 12px/20px Arial, sans-serif; } div { opacity: 0.7; position: relative; } h1 { font: inherit; font-weight: bold; } #div1, #div2 { border: 1px solid #696; padding: 10px; background-color: #cfc; } #div1 { z-index: 5; margin-bottom: 190px; } #div2 { z-index: 2; } #div3 { z-index: 4; opacity: 1; position: absolute; top: 40px; left: 180px; width: 330px; border: 1px solid #900; background-color: #fdd; padding: 40px 20px 20px; } #div4, #div5 { border: 1px solid #996; background-color: #ffc; } #div4 { z-index: 6; margin-bottom: 15px; padding: 25px 10px 5px; } #div5 { z-index: 1; margin-top: 15px; padding: 5px 10px; } #div6 { z-index: 3; position: absolute; top: 20px; left: 180px; width: 150px; height: 125px; border: 1px solid #009; padding-top: 125px; background-color: #ddf; text-align: center; } </style> </head> <body> <div id="div1"> <h1>Division Element #1</h1> <code>position: relative;<br/> z-index: 5;</code> </div> <div id="div2"> <h1>Division Element #2</h1> <code>position: relative;<br/> z-index: 2;</code> </div> <div id="div3"> <div id="div4"> <h1>Division Element #4</h1> <code>position: relative;<br/> z-index: 6;</code> </div> <h1>Division Element #3</h1> <code>position: absolute;<br/> z-index: 4;</code> <div id="div5"> <h1>Division Element #5</h1> <code>position: relative;<br/> z-index: 1;</code> </div> <div id="div6"> <h1>Division Element #6</h1> <code>position: absolute;<br/> z-index: 3;</code> </div> </div> </body> </html> View Code

效果:

澳门新萄京官方网站 21 

 分析一下:

1、因为设置了div {opacity: 0.7; position: relative;},所以#1~#6的z-index都是有效的。

2、为什么#4的z-index比#1高,但是却在#1下面?因为#4的z-index虽然值大,但它的作用域在包含块#3内,而#1的z-index的作用域在html内,和#3同属html,而#3的z-index小于#1。

3、为什么#2的z-index值比#5的大,还在下面?同上。

4、#3的z-index是4,但该值和#4,#5,#6的z-index不具有可比性,它们不在一个上下文环境。

5、如何轻易的判断两个元素的堆叠顺序?

z-index对堆叠顺序的控制类似于排版时候一大章下几个小节的样子,或者版本号中一个大的版本号跟着小版本号。

Root-z-index值为默认auto,即0

  • DIV #2 - z-index 值为2
  • DIV #3 - z-index 值为4
    • DIV #5 - z-index值为 1,其父元素z-index值 4,所以最终值为4.1
    • DIV #6 - z-index值为 3,其父元素z-index值 4,所以最终值为4.3
    • DIV #4 - z-index值为 6,其父元素z-index值 4,所以最终值为4.6
  • DIV #1 - z-index 值为5

想看更多例子,可参考文章最后的资源链接。

小结

到这里,可以得到一些结论:

  • 在同一个层叠上下文中计算层叠顺序时,根据前文所提到的规则来进行就是;
  • 对于不同的层叠上下文的元素,层级较大的层叠上下文中的元素用于处于层级小的层叠上下文中的元素之上(MG12将其归结为从父规则);
  • 从另一个角度理解,不同层叠上下文中的元素在计算层叠顺序时不会互相影响,因为在层叠上下文被创建的时候它与其他上下文的层叠顺序就早已经被决定了;

CSS中z-index属性具体是什?

层相对于屏幕纵深方向的顺序。你用几个层叠在一起就可看出它的含义。
如以下是相关测试代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "www.w3.org/...al.dtd">

<html xmlns="www.w3.org/1999/xhtml">
<head>
<title>无标题页</title>
</head>
<body>
<div style="position:relative; width:150px; height:100px; z-index:2; background-color:Red;"></div>
<div style="position:relative; width:150px; height:100px; z-index:1; top:-20px; background-color:Blue;"></div>
</body>
</html>

说明:
第一个DIV模块中,我们定义了宽度为150,高度为100,背景色为红色,z-index:2 inherit;此DIV的级别为2
第二个DIV模块中,我们定义了宽度亦为150,高度为100,背景色为蓝色,z-index:1 inherit;此DIV级别为1,top:-20px垂直向上-20象素.
2>1
上面的DIV模块级别高于下面的DIV模版级别.所以,我们在position:relative;中可以体会到是上一层遮住了下一层.并且遮住了我们设定的20象素的区域.  

六、 合理使用z-index数值

如果现有三个堆叠的层,从上到下分别为:DIV3,DIV2,DIV1,设置时以100为间隔,设置DIV1的z-index为0,DIV2的z-index为100,设置DIV3的z-index为200。这样后期如果需要在DIV1和DIV2之间加入一些层的话,以10为间隔,设置z-index为10,20等。再需要向z-index0和z-index10之间加入一层的话以5为间隔。这样的写法可以方便后期扩展添加内容。

尽量避免给z-index使用负值。当然不是绝对的,比如在做图文替换的时候可以使用负值。

创建层叠上下文

前文曾经提到,根元素以及z-indexauto的“positioned”元素可以会创建新的层叠上下文,这也是CSS2.1规范唯一提到的,但是在CSS3中,创建层叠上下文的触发条件有了修改,在MDN中有如下描述:

文档中的层叠上下文由满足以下任意一个条件的元素形成:

  • 根元素 (HTML),
  • 绝对(absolute)定位或相对(relative)定位且 z-index 值不为”auto”,
  • 一个 flex 项目(flex item),且 z-index 值不为 “auto”,也就是父元素 display: flex|inline-flex,
  • 元素的 opacity 属性值小于 1(参考 the specification for opacity),
  • 元素的 transform 属性值不为 “none”,
  • 元素的 mix-blend-mode 属性值不为 “normal”,
  • 元素的 isolation 属性被设置为 “isolate”,
  • 在 mobile WebKit 和 Chrome 22 内核的浏览器中,position: fixed 总是创建一个新的层叠上下文, 即使 z-index 的值是 “auto” (参考 这篇文章),
  • 在 will-change 中指定了任意 CSS 属性,即便你没有定义该元素的这些属性(参考 这篇文章)
  • 元素的 -webkit-overflow-scrolling 属性被设置 “touch”

CSS样式中z-index属性

定义和用法z-index 属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。注释:元素可拥有负的 z-index 属性值。注释:Z-index 仅能在定位元素上奏效(例如 position:absolute;)!  

如果你不是一名csser新手,想必你对z-index的用法应该有个大致的了解了吧,z-index可以控制定位元...

七、资源链接

MDN z-index

understanding css z-index

w3c z-index

 

一、z-index z-index用来控制元素重叠时堆叠顺序。 适用于 :已经定位的元素(即position:relative/absolute/fixed)。 一...

opacity的影响

在这里,我们看到了那个令人惊讶的opacity,原来它也创建了一个新的层叠上下文。为什么opacity小于1时需要创建新的层叠上下文呢?在CSS3-color中有这样的解释。

Since an element with opacity less than 1 is composited from a single offscreen image, content outside of it cannot be layered in z-order between pieces of content inside of it. For the same reason, implementations must create a new stacking context for any element with opacity less than 1.

由于一个opacity小于1的元素需要依靠这个元素以外的图像来合成,因此它外部内容不能根据z-index被层叠到该元素的内容中间(子元素也会变得透明,如果存在z-index不为auto的“positioned”子元素,那么这些子元素就需要与外部元素进行层叠计算,透明部分就会有奇怪的计算结果),因此它需要创建一个新的层叠上下文,以防止外部内容对该元素的透明化内容造成影响。

那么opacity对实际的层叠会有什么影响呢?规范中这样描述的:

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. See section 9.9 and Appendix E of [CSS21] for more information on stacking contexts. The rules in this paragraph do not apply to SVG elements, since SVG has its own rendering model ([SVG11], Chapter 3).

  • opacity小于1的“non-positioned”元素,它就会被当作一个z-index: 0opacity: 1的“positioned”元素一样,来进行层叠计算(前文规则中的第6层);
  • opacity小于1的“positioned”元素,它将按照前文中z-index的层叠规则计算技术,只不过,即使z-indexauto,仍然会创建层叠上下文;

回到之前讨论“不设置z-index的层叠”时用到的例子:

XHTML

<body> <div id="flodiv2">DIV #1</div> <div id="normdiv">DIV #2</div> <div id="flodiv2">DIV #3</div> <div id="normdiv">DIV #4</div> <div id="absdiv2">DIV #5</div> </body>

1
2
3
4
5
6
7
<body>
<div id="flodiv2">DIV #1</div>
    <div id="normdiv">DIV #2</div>
    <div id="flodiv2">DIV #3</div>
    <div id="normdiv">DIV #4</div>
    <div id="absdiv2">DIV #5</div>
</body>

DIV#3opacity设置为0.7,显示结果如下:

澳门新萄京官方网站 22

所有的opacity小于1的元素都是“positioned”,z-index默认为auto,即为0,根据规则6(层叠级数为0的子元素以及“positioned”且层叠级数为0的后代元素),它将不是浮动元素,而是一个“positioned”且层叠级数为0的元素,因此它将会被绘制到DIV#1之上(如果opacity为1,它应该是在DIV#1之下的);

如果仅将DIV#4设置opacity: 0.9,那么结果会是:

澳门新萄京官方网站 23

那么DIV#4就是opacity小于1的non-positioned元素,它将同样被当成z-index: 0opacity: 1 的 “positioned”元素一样,即是规则6(层叠级数为0的子元素以及“positioned”且层叠级数为0的后代元素),由于它与其他元素都处于z-index: 0,因此根据DOM树的顺序,它将仅在DIV#5之下。(即使将其他所有元素都设置opacity小于1,那么所有的这些元素都是根据规则6进行层叠计算,那么结果就是根据DOM树顺序产生)

Problem solved!!!

至于其他触发条件,就不再一一分析了。

总结

  • 元素设置了z-index后,必须将position设置为fixedabsoluterelative才回使z-index创建新的层叠上下文或生效;
  • 根元素(<html>)拥有一个根层叠上下文;
  • 计算层叠顺序时,需要先考虑元素所处的层叠上下文,层叠上下文之间的层叠关系直接决定了其元素集合之间的层叠关系(从父规则);
  • opacity及一些其他新的CSS3属性的设置也可能创建新的层叠上下文,这些属性的引入让层叠计算变得更加复杂;
  • 层叠计算规则基本是(不是最准确的描述):
    1. 创建层叠上下文的元素的背景和边界;
    2. z-index为负值的子元素;
    3. “non-positioned”的元素;
    4. “non-positioned”的浮动元素;
    5. “non-positioned”的内联元素(文本等);
    6. z-index为0的“positioned”元素;
    7. z-index大于等于1的“positioned”子元素;

层叠上下文是个比较少接触的概念,但这又是一个非常重要的概念,它决定了元素的层叠顺序的计算方式,尤其是利用z-index对元素层叠进行控制的时候,如果不理解层叠上下文的概念,就容易遇到各种各样奇怪的问题,有时候,这些问题被错误的归结为浏览器的“BUG”。实际上,大多数浏览器都是根据规范干活的,不要轻易地怀疑浏览器,而是要去看看规范中是怎样定义规则的。

本文大量参考并引用MDN上的文字和源码,并在其基础上作些许改动以求更简单明了的解释。如果对源码有疑问,请先去MDN上参考相关源码和文献。

本文是基于我对层叠上下文的学习和理解记录而成,由于自己是初学者,不敢保证文中所有观点都是正确的,因此我的观点仅作参考,若发现文中有错误,欢迎大家指出,我会尽快作出修正。

参考

Specifying the stack level: the ‘z-index’ property

Understanding CSS z-index

Stacking without z-index

Stacking and float

CSS Stacking Context里那些鲜为人知的坑

css3-color-#transparency

CSS z-index 属性的使用方法和层级树的概念

position 属性和 z-index 属性对页面节点层级影响的例子

1 赞 2 收藏 评论

澳门新萄京官方网站 24

本文由澳门新萄京官方网站发布于澳门新萄京赌场网址,转载请注明出处:index堆成堆法则,中的层叠上下文初探

关键词: