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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,703评论 1 92
  • z-index 与 css 定位属性 z-index 只对定位元素有作用。 如果定位元素z-index没有发生嵌套...
    soojade阅读 831评论 0 2
  • 第一节:z-index基础 较大的z-index会覆盖较小的那个z-index元素 z-index:auto 默认...
    胖鱼尾巴阅读 955评论 0 0
  • 1.z-index简介 (1) 概念 z-index属性指定了元素与元素之间的z轴上的顺序,而z轴决定元素之间发生...
    Bennt阅读 23,902评论 2 10
  • CSS 定位 CSS有三种基本的定位机制:普通流,浮动,绝对定位(absolute, fixed):普通流是默认定...
    _空空阅读 5,698评论 0 15