CSS:Stacking Context

通常情况下,HTML页面可以被认为是二维的,因为文本,图像和其他元素被排列在页面上而不重叠。在这种情况下,只有一个渲染进程,所有元素都知道其他元素所占用的空间。z-index属性可让你在渲染内容时调整对象分层的顺序,相信大部分人都用过position,当父元素设置了position,子元素设置position:absolute,默认是覆盖在元素上的,其实里面就隐藏了z-index的应用,今天来彻底了解这个z-index

这边先讲个概念:层叠上下文,什么是层叠上下文:这边可以讲层叠上下文理解成一个属性,只有触发了某些特定条件才能激发这个属性,网页中有很多很多的元素,一个网页就是一个dom树,除了root(根结点),每个元素注定有父级,一个父级含有层叠上下文这个属性并且离当前元素最近,这个父元素就称为当前元素的层叠上下文容器,这里的概念和绝对定位概念一样,绝对定位是寻找当前元素最近的父元素并且含有position的属性(除了值为static)作为定位位置。

我们经常在布局时没有用到z-index,但是也能搞出我们想要的结果,比如:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head><style type="text/css">

div {
   font: 12px Arial;
}

span.bold { font-weight: bold; }

#normdiv {
   height: 70px;
   border: 1px dashed #999966;
   background-color: #ffffcc;
   margin: 0px 50px 0px 50px;
   text-align: center;
}

#reldiv1 {
   opacity: 0.7;
   height: 100px;
   position: relative;
   top: 30px;
   border: 1px dashed #669966;
   background-color: #ccffcc;
   margin: 0px 50px 0px 50px;
   text-align: center;
}

#reldiv2 {
   opacity: 0.7;
   height: 100px;
   position: relative;
   top: 40px;
   left: 20px;
   border: 1px dashed #669966;
   background-color: #ccffcc;
   margin: 0px 50px 0px 50px;
   text-align: center;
}

#absdiv1 {
   opacity: 0.7;
   position: absolute;
   width: 150px;
   height: 350px;
   top: 10px;
   left: 10px;
   border: 1px dashed #990000;
   background-color: #ffdddd;
   text-align: center;
}

#absdiv2 {
   opacity: 0.7;
   position: absolute;
   width: 150px;
   height: 350px;
   top: 10px;
   right: 10px;
   border: 1px dashed #990000;
   background-color: #ffdddd;
   text-align: center;
}

</style></head>

<body>

<br /><br />

<div id="absdiv1">
   <br /><span class="bold">DIV #1</span>
   <br />position: absolute;
</div>

<div id="reldiv2">
   <br /><span class="bold">DIV #3</span>
   <br />position: relative;
</div>

<div id="reldiv1">
   <br /><span class="bold">DIV #2</span>
   <br />position: relative;
</div>

<div id="absdiv2">
   <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>

运行结果:

上面所有元素都没有设置z-index,其实都是默认值:auto,按照MDN讲的:

当没有元素包含z-index属性时,元素按照如下顺序堆叠(从底到顶顺序):

  1. 根元素的背景和边界
  2. 普通流(无定位)里的块元素(没有position或者position:static;)按HTML中的出现顺序堆叠
  3. 定位元素按HTML中的出现顺序堆叠

基本是按照HTML出现顺序堆叠的。

我们再来开个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>

    html{
        background-color: gray;
    }
    .test{
        width: 300px;
        height: 300px;
        background-color: deepskyblue;
    }

</style>
<body>
    <div class="test">
        <!-- img属于行内替换元素,可设置width,height -->
        <img src="test01.jpg" width="100px" height="100px" >
        </div>
    </div>
</body>
</html>

~嗯,这很正常,按照顺序,后面覆盖前面的,现在在img上面加个:z-index: -1;我以为它会跑div下面去,然而并没有任何改变,我们再加个position:relative;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>

    html{
        background-color: gray;
    }
    .test{
        width: 300px;
        height: 300px;
        background-color: deepskyblue;
    }
     img:nth-child(1){
         z-index: -1;
         position: relative;
    }
</style>
<body>
    <div class="test">
        <img src="test01.jpg" width="100px" height="100px" >
        </div>
    </div>
</body>
</html>

不见了,跑下面去了,为了让它更值观点,设置left:250px;

还真的在下面,为什么加了position:relative后,z-index才起作用?

借用张鑫旭的关于z-index的一句话:对于包含有position:relative/position:absolute的定位元素,以及FireFox/IE浏览器(不包括Chrome等webkit内核浏览器)(目前,也就是2016年初是这样)下含有position:fixed声明的定位元素,当其z-index值不是auto的时候,会创建层叠上下文,也就是说普通元素使用z-index是没有作用的。

这里有个层叠顺序图:

按照上面的顺序,background是最低层,为什么图片还会比它更低?这是因为当前的层叠上下文容器不是<div class="test"></div>,还记得上面讲过,寻找层叠上下文的机制跟position:absolute简直一样,所有一直向上找,知道根结点html,因为html默认包含层叠上下文这个属性,所以结果就是那样了。

我们可以给div触发层叠上下文,这样图片就又浮上来了:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>

    html{
        background-color: gray;
    }
    .test{
        width: 300px;
        height: 300px;
        background-color: deepskyblue;

/*触发层叠上下文*/
/*混合模式*/
mix-blend-mode: exclusion;
/*触发层叠上下文*/
/*opacity: 0.9;*/
/*触发层叠上下文*/
/* position: absolute;
z-index: 0;


*/
/*触发层叠上下文*/
/*transform:rotate(1deg);*/

     img:nth-child(1){
         z-index: -1;
         position: relative;
         left: 250px;
    }
</style>
<body>
    <div class="test">
        <img src="test01.jpg" width="100px" height="100px" >
        </div>
    </div>
</body>
</html>

借用张鑫旭的测试结果,因为css3新特性很多,所以很多属性都可以触发层叠上下文,他说下面这几种可以触发层叠上下文:

  1. z-index值不为autoflex项(父元素display:flex|inline-flex).
  2. 元素的opacity值不是1.
  3. 元素的transform值不是none.
  4. 元素mix-blend-mode值不是normal.
  5. 元素的filter值不是none.
  6. 元素的isolation值是isolate.
  7. will-change指定的属性值为上面任意一个。
  8. 元素的-webkit-overflow-scrolling设为touch.

但是我们只要记我们常用的就好了。

还有一个要注意的是,两个层叠上下文里面的子元素的z-index没有可比性,一切得看父元素。

比如A元素有a,b,c;

B元素有d,e,f;

当A的z-index比B高时,B里面的d,e,f的z-index再怎么高都不会比A中任意一个元素高。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<style>

    html{
        background-color: gray;
    }
    .test01{
        width: 300px;
        height: 300px;
        background-color: deepskyblue;
        position: absolute;
        z-index: 2;
    }
    .test01 img{
        z-index: 10;
         position: absolute;
         left: 250px;
    }
    .test02{
        position: absolute;
        top: 80px;
        left: 400px;
        width: 300px;
        height: 300px;
        z-index: 1;
        background-color: orange;
    }
    .test02 img{
        z-index: 100;
         position: absolute;
         left: 250px;
    }
</style>
<body>
    <div class="test01">
        父级z-index:2
        图片z-index:10
        <img src="test01.jpg" width="100px" height="100px" >
        </div>
    </div>
    <div class="test02">
        父级z-index:1
        图片z-index:100
        <img src="test02.jpg" width="100px" height="100px">
    </div>
</body>
</html>

如上图所示,现在讲第二个div移到第一个div一样的位置,将css中的.test02的left:400p去掉,看下哪个图片在上面:

嗯,结果跟我们想的一样,z-index在平时我们不怎么写,但其实到处都在用,就说个最简单的例子,我们要让一些文本围着一张图片说明:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Document</title>
</head>
<style>
   .test{
      width: 500px;
      height: 500px;
      border: 1px solid black;
   }
   .test img{
      float: left;
      margin-right:-50px;
   }
</style>
<body>

   <div class="test">
      这是对张图片的说明这是对张图片的说明这是对张图片的说明这是对张图片的说明
      这是对张图片的说明这是对张图片的说明这是对张图片的说明这是对张图片的说明
      <img src="test01.jpg" width="100px" height="100px">
      这是对张图片的说明这是对张图片的说明这是对张图片的说明这是对张图片的说明
      这是对张图片的说明这是对张图片的说明这是对张图片的说明这是对张图片的说明
   </div>
</body>
</html>

讲下原理:因为img加了float所以脱离了普通流,进入了浮动流,除了块级元素看不到浮动流,其他元素都可以看到浮动流,所以文字就飘过去了,又因为加了margin-right:-50px;因为浮动不能超过父元素,所以文字有可以向左移动50px,但是图片还是那。对应上面的层叠顺序图,结果符合。那为什么要这样设计(得问设计者),因为文字(inline)是网页中比较重要的一个元素,所以z-index地位就比较高一点。

本文简化张鑫旭写的:深入理解CSS中的层叠上下文和层叠顺序

有错的话,欢迎指正??。

原文地址:https://www.cnblogs.com/doudoublog/p/8890959.html

时间: 2024-10-09 19:23:16

CSS:Stacking Context的相关文章

关于stacking context和CSS z-index的总结

HTML中决定元素叠加顺序的CSS属性最有名的应该是z-index了.但是,往往在项目中发现有些情况和我们的预期不太一致.经过研究和学习,总算搞清楚了其中的关系.简单总结如下: 只有Positioned(Position不为static的元素)元素的z-index属性才有效 z-index可以是负数 没有z-index或z-index无效的元素(参见第一条)相当于z-index为0: 符合某些条件的元素,浏览器会为它们创建一个叫stacking context的东东.根据DOM树结构,stack

CSS - 层叠上下文(The stacking context)

对 MDN 的上的例子的拓展 Root - DIV #1(z-index: 5) - DIV #2(z-index: 2) - DIV #3(z-index: 4) - DIV #4(z-index: 6) - DIV #5(z-index: 1) - DIV #6(z-index: 3) - DIV #7(未设置 z-index, 且 opacity: 1) - DIV #8(z-index: 6) 上面结构中 DIV #4 的 z-index 比 DIV #1 的大,但因为 DIV #3 创

css中的opacity和z-index对于stacking context的影响

今天偶尔看到了一篇文章讲z-index的, 有一些新的收获吧, 记录一下. 他给了一个例子: 1 <div> 2 <span class="red">Red</span> 3 </div> 4 <div> 5 <span class="green">Green</span> 6 </div> 7 <div> 8 <span class="blu

深入理解CSS中的层叠上下文和层叠顺序(转)

by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=5115 零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在CSS届,也是如此.只是,一般情况下,大家歌舞升平,看不出什么差异,即所谓的众生平等.但是,当发生冲突发生纠葛的时

深入理解CSS中的层叠上下文和层叠顺序

零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在CSS届,也是如此.只是,一般情况下,大家歌舞升平,看不出什么差异,即所谓的众生平等.但是,当发生冲突发生纠葛的时候,显然,是不可能做到完全等同的,先后顺序,身份差异就显现出来了.例如,杰克和罗斯,只能一人浮在木板上,此时,出现了冲突,结果大家都知道的.那对于CSS世界中的元素而言,所谓的“冲突”指什

CSS 3 学习——transform 3D转换渲染

以下内容根据官方规范翻译,没有翻译关于SVG变换的内容和关于矩阵计算的内容. 一般情况下,元素在一个无景深无立体感的平面(flat plane)上渲染,这个平面就是其包含块所处的平面.同时,页面上的其他元素也共享这个平面.2D变换函数虽然能改变元素的表现,但是这个被改变的元素仍然是在其包含块所处的平面内被渲染. 3D变换会产生一个变换矩阵,该变换矩阵在Z轴上的分量不为0.结果是把元素渲染到一个不同于其包含块所处的平面内.这将影响到通常情况下的"后来居上"的渲染规则:变换元素可能会和其相

CSS 定位元素之 relative

1. relative 和 absolute relative 会限制 absolute. absolute 会根据 父级的的定位元素来定位. 2. overflow 和 absolue 当overflow碰到 absolute的时候 overflow会失效 如果要overflow有效 必须使用relative 和 fixed.   3. relative 和 层级 z-index 当使用relative的时候 自身的层级并不能决定你 的层级位置 而是要看relative的层级 relative

CSS教程:彻底掌握Z-index属性

大多数的CSS属性都很容易使用.常常,当您对标记语言的元素使用CSS属性时,产生的结果会随着您刷新页面而立即呈现.而另一些CSS属性,却会有一些复杂,且只能在给定的环境下才会工作. Z-index属性便属于上面所说的后面的那一组.Z-index无疑的比其他任何属性都会频繁的导致(兼容性)上 的混乱和(开发者心理上)的挫败感.但滑稽的是,一旦你真正理解了Z-index,你会发现它却是一个非常容易使用的属性,并且会为解决很多layout 方面的挑战提供强有力的帮助. 在这篇文章里,我们会准确的说明究

CSS中transform 属性

CSS中transform 属性允许你修改CSS可视化模型的坐标空间.通过transform,可以让元素进行移动(translate).旋转(rotate).缩放(scale).倾斜(skew). 如果该属性有一个非none值, 将会产生一个层叠上下文. 在这种情况下 对象将作为它包含的 position: fixed 元素的包含块(a containing block). 初始值 none 适用元素 transformable elements 是否是继承属性 否 Percentages re