z-index堆叠规则

简介:

一、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时堆叠顺序

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

  • 根元素(即HTML元素)的background和borders
  • 正常流中非定位后代元素(这些元素顺序按照HTML文档出现顺序)
  • 已定位后代元素(这些元素顺序按照HTML文档出现顺序)
解释一下后两条规则:
  • 正常流中非positoned element元素,总是先于positioned element元素渲染,所以表现就是在positioned element下方,跟它在HTML中出现的顺序无关。
  • 没有指定z-index值的positioned element,他们的堆叠顺序取决于在HTML文档中的顺序,越靠后出现的元素,位置越高,和position属性无关

例子:

复制代码
<!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>
复制代码

有图有真相:

 分析:

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

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

三、浮动堆叠顺序

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

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

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

举例:

复制代码
<!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;
    }

    #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>
复制代码

分析:

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

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

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

 

四、z-index

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

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

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

举例:

  View Code

五、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" (Seethis 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
复制代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" 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>
复制代码

效果:

 

 分析一下:

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

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

六、 合理使用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使用负值。当然不是绝对的,比如在做图文替换的时候可以使用负值。

七、资源链接

MDN z-index

understanding css z-index

  1. Stacking without z-index : Default stacking rules
  2. Stacking and float : How floating elements are handled
  3. Adding z-index : Using z-index to change default stacking
  4. The stacking context : Notes on the stacking context
  5. Stacking context example 1 : 2-level HTML hierarchy, z-index on the last level
  6. Stacking context example 2 : 2-level HTML hierarchy, z-index on all levels
  7. Stacking context example 3 : 3-level HTML hierarchy, z-index on the second level

w3c z-index

 

本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http://www.cnblogs.com/starof/p/4424926.html有问题欢迎与我讨论,共同进步。

相关文章
|
12月前
|
人工智能 算法 搜索推荐
《智育新篇:点亮学生人工智能伦理与社会责任之光》
在人工智能迅猛发展的时代,其应用已渗透到生活的方方面面,深刻改变着我们的生活模式与社会架构。然而,随之而来的伦理和社会责任问题也日益凸显。教育者需在课堂中融入伦理思辨,通过具体案例引导学生理解AI的伦理边界,如人脸识别技术的应用与隐私保护、智能机器人决策中的道德困境等。同时,培养学生的社会责任意识,使其认识到AI应服务于社会福祉,避免因商业利益导致资源分配不均。学校应搭建多元实践平台,鼓励学生参与公益项目和政策讨论,增强其对社会责任的情感认同。在全球化背景下,拓展国际视野,深化跨文化交流,共同应对AI带来的全球性挑战。
468 25
|
12月前
|
传感器 机器学习/深度学习 人工智能
《智领新材制造:人工智能点亮新材料良品率提升之路》
在新材料生产中,人工智能通过精准监测、故障预警、智能优化工艺参数、智能化质量检测及预测性维护,全方位提升生产良品率。它结合传感器实时数据,快速识别异常并优化参数,确保产品质量一致性。机器视觉和无损检测技术提高缺陷识别精度,预测性维护保障设备稳定运行。尽管面临挑战,AI正重塑新材料生产模式,助力产业高质量发展。
238 4
Dreamweaver是怎么把图片转换成代码 简单五步骤即可解决
Dreamweaver是怎么把图片转换成代码的呢?其实利用Dreamweaver是可以将图片装换成代码的
675 5
|
移动开发 JSON JavaScript
|
存储 编解码 生物认证
华为Mate 10和Mate 10 Pro终极对比,结果很尴尬?
去年12月,作为华为的两大高端型号之一,Mate 9系列同时推出了普通版、pro版和保时捷版,后两者作为向高端市场的进一步上探并收到了不错的市场反响后。今年华为再接再厉,继续推出了Mate 10系列的普通版、pro版和保时捷版。
971 0
华为Mate 10和Mate 10 Pro终极对比,结果很尴尬?
|
人工智能 Cloud Native 安全
阿里云新品发布会周刊第103期 丨 阿里云多账号管控与网络安全集中化管理能力升级
2019年-2023年,中国金融云解决方案市场年复合增长率将达到40.2%,2023年,市场规模将达到35.9亿美元,而建设核心将重点围绕数据管理与分析展开。本次发布会,阿里云原生多模数据库Lindorm联合智臾科技DolphinDB正式发布金融时序大数据量化分析解决方案。
1229 0
阿里云新品发布会周刊第103期 丨  阿里云多账号管控与网络安全集中化管理能力升级
|
机器学习/深度学习 人工智能 自然语言处理
关于人工智能你需要知道的一切
通常情况下,人工智能系统至少会表现出与人类智能相关的以下某些行为:计划、学习、推理、问题解决、知识表示、感知、运动和操纵,在某些程度上还包括社会智能和创造力。
618 0
关于人工智能你需要知道的一切
|
监控 数据可视化 关系型数据库
互联网、电商及游戏行业实时BI分析
本文以电商行业为例,将业务数据和日志数据同步到ADB,之后通过Quick BI做实时可视化分析。相对于传统的关系型数据库,阿里云分析型数据库MySQL版只需要几毫秒的时间,即可查询PB级数据并从中找到匹配信息。
互联网、电商及游戏行业实时BI分析
|
算法框架/工具 算法 异构计算
MNN - 端侧推理引擎面临的挑战与应对
MNN(Mobile Neural Network)已于今年5月7日在 Github 上正式开源。
3007 0
|
Arthas 监控 Java
更效率、更优雅 | 阿里巴巴开发者工具不完全盘点
阿里巴巴将自身在各类业务场景下的技术积淀,通过开源、云上实现或工具等形式对外开放,本文将精选了一些阿里巴巴的开发者工具,希望能帮助开发者们提高开发效率、更优雅的写代码。
3381 0