CSS理解之z-index

1.z-index基础

z-index属性指定了元素及其子元素的[z顺序],而[z顺序]可以决定 当元素发生覆盖的时候,哪个元素在上面。通常一个较大z-index值的元素会覆盖较低的那一个。

z-index支持的属性值:

1. z-index:auto;默认值,如果不对z-index设置,默认为auto;
2. z-index:<integer>;整数值,z-index:1,z-index:2等
3. z-index:inherit;继承

z-index基本特性:

1. 支持负值;
2. 支持CSS3  animation动画;
3. 在CSS2.1时代,不考虑CSS3,z-index要起作用需要和定位元素配合使用,只有定位元素(position:relative/absolute/fix/sticky)设置z-index才有作用(CSS3中有例外);

2. z-index与定位元素

如果定位元素发生了覆盖,且没有嵌套(不是一个定位元素里面嵌套着另一个定位元素),谁在上面遵守下面两个准则:

1. 后来居上的准则,后面的覆盖前面的;
2. z-index哪个大,哪个上;

demo 1:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div1 img{
            position: absolute;
        }
        .div2 img{
            position: relative;
            margin-left: 100px;
        }
    </style>
</head>
<body>
    <div class="div1">
        ![](a.jpg)
    </div>
    <div class="div2">
        ![](b.jpg)
    </div>
</body>
</html>

Paste_Image.png

后面的定位元素覆盖前面的定位元素在上面渲染。

demo 2:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div1 img{
            position: absolute;
            z-index:2;
        }
        .div2 img{
            position: relative;
            z-index:1;
            margin-left: 100px;
        }
    </style>
</head>
<body>
    <div class="div1">
        ![](a.jpg)
    </div>
    <div class="div2">
        ![](b.jpg)
    </div>
</body>
</html>

Paste_Image.png

z-index值大的在上面覆盖z-index值小的

另一种情况:定位元素z-index发生了嵌套,谁在上面遵循如下原则:

  1. 祖先优先原则; demo :
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div1 img{
            position: absolute;
            z-index:3;
        }
        .div2 img{
            position: relative;
            z-index:-1;
            margin-left: 100px;
        }
    </style>
</head>
<body>
    <div class="div1" style="position: relative;z-index: 1;">
        ![](a.jpg)
    </div>
    <div class="div2" style="position: relative;z-index: 3;">
        ![](b.jpg)
    </div>
</body>
</html>

Paste_Image.png

可以看到嵌套了的z-index定位元素,尽管前面的子元素的z-index值大,还是后面的图片覆盖了前面的,这里就遵循了祖先优先原则。

前提:祖先的z-index值是数值不是auto

demo :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div1 img{
            position: absolute;
            z-index:2;
        }
        .div2 img{
            position: relative;
            z-index:1;
            margin-left: 100px;
        }
    </style>
</head>
<body>
    <div class="div1" style="position: relative;z-index: auto;">
        ![](a.jpg)
    </div>
    <div class="div2" style="position: relative;z-index:1;">
        ![](b.jpg)
    </div>
</body>
</html>

Paste_Image.png

当第一个图片元素的祖先元素z-index值为auto时,祖先优先原则就会失效,z-index:auto可以看成是z-index:0,尽管第二个图片元素的祖先元素z-index值比0大,但还是第一个图片覆盖第二个图片。 CSS2.1:(z-index:auto时)当前层叠上下文的生成盒子层叠水平是0。盒子(除非是根元素)不会创建一个新的层叠上下文。这是起作用的反而是子元素的z-index值。第一个子元素的z-index大于第二个子元素的,所以会覆盖。

3.CSS中层叠上下文和层叠水平

层叠上下文(stacking content)是HTML元素中的一个三维概念,表示元素在z轴上有了“高人一等”。

页面根元素天生具有层叠上下文,称之为"根层叠上下文"

z-index值为数值的定位元素也具有层叠上下文

层叠上下文中的每个元素都有一个层叠水平(stacking level),决定了同一个层叠上下文中元素在z轴上的显示顺序。几乎所有的元素都有层叠水平,但是要放在层叠上下文中来看。

层叠水平和z-index不是一个东西。普通元素也有层叠水平,但z-index只在定位元素上起作用。

同一个层叠上下文中的层叠元素遵循“后来居上”“谁大谁上”的层叠原则。

层叠上下文几个特性:

  • 层叠上下文可以嵌套(父元素中嵌套子元素),组成一个分层次的层叠上下文。
  • 每个层叠上下文和兄弟元素独立:当进行层叠变化或渲染的时候,只需要考虑后代元素
  • 每个层叠上下文是自成体系的:当元素的内容被层叠后,整个元素被认为是在父层的层叠顺序中

4.理解元素的层叠顺序(stacking order)

层叠顺序:元素发生层叠时候有着特定的垂直显示顺序。

著名的7阶层叠水平(stacking level),用来判断元素发生层叠时谁在上谁在下:

Paste_Image.png

层叠元素的意义:

规范元素重叠时候的呈现规则。

为何层叠顺序是上面图片中的样子?比如:为何内联元素会覆盖浮动元素?

之所以是这样的七阶,是因为这样更符合加载的功能和视觉呈现

一般来说,像background/border是用来装饰的,块状元素、浮动元素都是用来布局的,而内联元素绝大部分是内容:图片、文字,因为内容是页面最重要的部分,因此层叠必须水平要高,重要的东西越要往上面放!

demo :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
       img{
        float: left;
        margin-right: -40px;
        width: 250px;
        height: 400px;
       }
    </style>
</head>
<body>
        ![](b.jpg)
        <span>
            以前浮动课学过,浮动设计的作用是实现文字环绕图片的效果。如果文字和
            图片发生重叠,显然,是后面的文字要优先显示的,因为,文字比图片重要。
        </span>
</body>
</html>

这里把图片变成了浮动元素,内容(内联元素)覆盖了图片浮动元素,比浮动元素的层叠水平要高。

Paste_Image.png

demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
       .inline-block,.block{
           width: 400px;
           height: 200px;
           position: relative;
       }
       .inline-block{
           display: inline-block;
           background-color: olive;
           margin: -30px; 
       }
       .block{
           display: block;
           background-color: green;
       }
    </style>
</head>
<body>
    <div class="inline-block">
        display:inline-block
    </div>
    <div class="block">
        display:block;
    </div>
</body>
</html>

Paste_Image.png

内联元素比块状元素的层叠水平高,上面的背景色覆盖了下面的,但是下面的文字覆盖了上面的背景色。这是因为:背景色的覆盖是层叠顺序,文字的覆盖是后来居上原则。文字是inline元素和inline-block是平级的,所以这里要用到后来居上原则

5.z-index与层叠上下文(解释z-index的实际行为表现)

三个行为要点:

1. 定位元素默认的`z-index:auto`可以看成是z-index:0
2.z-index不为auto的定位元素会创建层叠上下文;
3.z-index层叠顺序的比较止步于父级层叠上下文;

第一个行为要点:定位元素默认的z-index:auto可以看成是z-index:0;

demo 1:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
       
       .img1,.img2{
            width: 200px;
            height: 400px;
       }
       .img1{

       }
       .img2{
           margin-left: -60px;
       }
    </style>
</head>
<body>
    ![](a.jpg)
    ![](b.jpg)
</body>
</html>

Paste_Image.png

根据后来居上原则后面的元素会覆盖前面的元素

demo 2:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
       
       .img1,.img2{
            width: 200px;
            height: 400px;
       }
       .img1{
            position: relative;
       }
       .img2{
           margin-left: -60px;
       }
    </style>
</head>
<body>
    ![](a.jpg)
    ![](b.jpg)
</body>
</html>

Paste_Image.png

第一个图片变成定位元素之后,前面的图片又覆盖了后面的,这是因为当变为定位元素后,没有对z-index设置值,所以默认值为auto,从层叠顺序上看,这时可以把z-index:auto看成是z-index:0。这时再对照七阶层叠那个图:

Paste_Image.png

第二个行为要点:z-index不为auto的定位元素会创建层叠上下文

demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div2{
            position: absolute;
            background: blue;
            width: 200px;
            height: 400px;
            margin-left: 100px;
        }
        .div2 img{
            position: relative;   
            margin-left: -100px;
            z-index: -1;
        }
    </style>
</head>
<body>
   
    <div class="div2">
        ![](a.jpg)
    </div>
</body>
</html>

Paste_Image.png

绝对定位元素只是一个普通元素,并不具有层叠上下文。此时图片的层叠上下文是页面根元素。所以背景色会覆盖图片。

一旦给父元素z-index值为数值不为auto时,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .div2{
            position: absolute;
            background: blue;
            width: 200px;
            height: 400px;
            margin-left: 100px;
            z-index: 0;
        }
        .div2 img{
            position: relative;   
            margin-left: -100px;
            z-index: -1;
        }
    </style>
</head>
<body>
   
    <div class="div2">
        ![](a.jpg)
    </div>
</body>
</html>

Paste_Image.png

当我们给父元素.div设置z-index:0;时,就创建了层叠上下文,此时图片的层叠上下为文就变成了容器。z-index负值的层叠顺序在层叠上下文元素的背景色之上。

Paste_Image.png

从层叠顺序上讲,z-index:auto可以看成z-index:0。但是从层叠上下文来讲,两者却有着本质差异!本质差异:z-index:auto不可以创建层叠上下文,z-index:0可以。

第三个行为要点:z-index受限于层叠上下文

demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
       
       .img1,.img2{
            width: 200px;
            height: 400px;
       }
       .box1{
         position: relative;
         z-index: 0;
       }
       .box1 img{
          position: absolute;
          z-index: 99999;
       }
       .box2{
          position: relative;
          z-index: 1;
          margin-left: 120px;
       }
       .box2 img{
          position: absolute;
          z-index: -1;
       }
    </style>
</head>
<body>
    <div class="box1">
        ![](a.jpg)
    </div>
    <div class="box2">
        ![](b.jpg)
    </div> 
</body>
</html>

Paste_Image.png

可以看到尽管第一个图片的z-index远远大于第二个图片,但是由于第二个图片的父元素的层叠顺序大于第一个图片父元素的层叠顺序,所以最终的行为表现仍然是后面的覆盖前面的。

6.其他CSS属性与层叠上下文(不只是z-index)

1.页面根元素天生具有层叠上下文,称之为"根层叠上下文"。 2.z-index值为数值的定位元素(相对或绝对)也具有层叠上下文。 3.其他属性......创建层叠上下文。

Paste_Image.png

demo 1:display:flex与层叠上下文

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Document</title>
   <style>
       .box{
           background: blue;
           width: 300px;
           height: 500px;
           margin: 0 auto;
       }
       .box>div{
           z-index: 1;
       }
       .box>div>img{
           position: relative;
           z-index: -1;
           margin-left: -100px;
       }
   </style>
</head>
<body>
   <div class="box">
       <div>
           ![](a.jpg)
       </div>
   </div>
</body>
</html>

Paste_Image.png

由于.box不是层叠上下文元素,所以图片没有覆盖背景色,此时图片的层叠上下文为根元素。

当我们为.box设置display:flex之后:

Paste_Image.png

图片覆盖了背景色。

注意:给.box设置display:flex不是.box变为了层叠上下文元素,而是它的子项变成了层叠上下文元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .box{
            background: blue;
            width: 300px;
            height: 500px;
            margin: 0 auto;
            display: flex;
        }
        .box>div{
            z-index: auto;
        }
        .box>div>img{
            position: relative;
            z-index: -1;
            margin-left: -100px;
        }
    </style>
</head>
<body>
    <div class="box">
        <div>
            ![](a.jpg)
        </div>
    </div>
</body>
</html

Paste_Image.png

当对它的子元素的z-index值设置.box>div{ z-index: auto; }后,.box元素的子项就不再是层叠上下文元素了

demo 2 :opacity ≠ 1 与层叠上下文

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .box{
            background: blue;
            width: 300px;
            height: 500px;
            margin: 0 auto;
        }
        .box img{
            position: relative;
            z-index: -1;
            margin-left: -100px;
        }
    </style>
</head>
<body>
    <div class="box">
        ![](a.jpg)
    </div>
</body>
</html>

Paste_Image.png

当我们为.box元素设置opacity为0.5时:

Paste_Image.png

图片显示在了背景色上面,这是因为opacity ≠ 1的元素为层叠上下文元素。

demo 3 :transform ≠ none 与层叠上下文

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .box{
            background: blue;
            width: 300px;
            height: 500px;
            margin: 0 auto;
            transform: rotate(15deg);
        }
        .box img{
            position: relative;
            z-index: -1;
            margin-left: -100px;
        }
    </style>
</head>
<body>
    <div class="box">
        ![](a.jpg)
    </div>
</body>
</html>

Paste_Image.png

transform ≠ none的元素为层叠上下文元素.

......以上不过多赘述。

7.z-index与其它CSS属性层叠上下文(非定位元素层叠上下文和z-index关系)

1.不支持z-index的层叠上下文元素的层叠顺序均是z-index:auto级别(不支持z-index的层叠上下文,指的就是那些CSS属性创建的层叠上下文)。

Paste_Image.png

举个例子:

Paste_Image.png

上图中img1、img2、img3、img4、img5依次相互覆盖,img1对应七阶层叠水平中的第五阶,是inline水平元素,img2、img4、img5是不依赖z-index的层叠上下文,img3是z-index:auto,它们都对应第六阶,属于同阶,遵循后来居上原则,依次覆盖。

2.依赖z-index的层叠上下文元素的层叠顺序取决于z-index值

     依赖z-index值创建层叠上下文的情况:

1.position值为relative/absolute或fixed(部分浏览器); 2.display:flex|inline-flex容器的子flex项;

Paste_Image.png

Paste_Image.png

上图中的.box元素是普通元素,它的子项才是层叠上下文元素,所以不仅被第一张图片覆盖,还被父元素的背景色覆盖

Paste_Image.png

Paste_Image.png

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从零开始学自动化测试

selenium+python自动化86-循环点击遇到的坑

# 前言 selenium定位一组元素,批量操作循环点击的时候会报错:Element not found in the cache - perhaps the ...

5334
来自专栏闻道于事

Layui常见问题

为什么表单不显示?当你使用表单时,Layui会对select、checkbox、radio等原始元素隐藏,从而进行美化修饰处理。但这需要依赖于form组件,所以...

4195
来自专栏python3

tkinter -- Grid

实现机制是将 Widget 逻辑上分割成表格,在 指定的位置放置想要的 Widget 就可以了

723
来自专栏互联网软件技术

添加标签——给定标签选项

1014
来自专栏Objective-C

iOS-逻辑思维面试题01

2778
来自专栏小古哥的博客园

读书笔记《CSS权威指南》

阅读本书主要目的: 自从学会CSS以来,虽然熟练掌握了其使用方法和技巧,但对其底层的原理和实现并不清晰,阅读本书想进一步系统化的学习和深入研究其本质,对这门前端...

3275
来自专栏吾爱乐享

php学习之css入门(一)

1252
来自专栏从零开始学 Web 前端

从零开始学 Web 之 jQuery(二)获取和操作元素的属性

DOM中有很多方式获取元素,比如通过id,通过标签名,通过类名,通过name的值,通过选择器等方式。

1054
来自专栏练小习的专栏

可视化格式模型-clear特性

‘clear’特性 该特性表明一个元素框的哪一边不可以和先前的浮动框相邻。’clear’特性不考虑它自身包含的浮动子元素和不处于同一个Block formatt...

1766
来自专栏极客慕白的成长之路

系统讲解CSS应用

<input type="radio" name="radio1" id="radio1-2" /> <label for="radio1-2">选项二</la...

441

扫码关注云+社区