层叠上下文

456 阅读3分钟

这是我参与更文挑战的第9天,活动详情查看: 更文挑战

层叠上下文

在网页中的每个元素其实都存在x,y,z三个方向的位置,当两个元素在z方向上的位置不同,就形成了层叠关系。z坐标越大,离用户越近,也就越往上。

层叠的触发

  1. 根元素

  2. 父元素display:flex|inline-flex,子元素z-index不为auto

    当一个元素的父元素是flex,子元素只要设置z-index就能触发子元素的层叠。

  3. 元素的postion值为absoluterelativefixedsticky

    当不设置他们的z-index时候,他们的层级和其他不支持z-index的属性一致,如transform: xxxposition: relative的层级是一致的,原因是他们的z-index都是auto。

  4. 元素的opacity值不是1

  5. 元素的transform值不是none

  6. 元素mix-blend-mode值不是normal

  7. 元素的filterprespectiveclip-pathmaskmask-imagemask-bordermotion-path值不是none

  8. 元素的isolation值是isolate

  9. will-change指定的属性值为上面任意一个

  10. 元素的-webkit-overflow-scrolling设为touch

层叠等级

2016-01-09_211116-1624974750778.png

有几个注意点:

  1. 如果两个元素层叠上下文位于同一层,就采取后来居上的原则。

  2. 需要注意的是,最低一层是已经触发层叠的background,而第三层那个是普通文档流的块级、非定位元素。具体看下代码:

    <head>
        <style> 
            .box1 { 
                background-color:pink; 
                width: 100px; 
                height: 100px;
                /* transform: scale(1); */
            }
            .box2 { 
                position: relative; 
                z-index: -1;
                background-color: #abcdef;
                width: 50px;
                height: 50px;
            }
        </style>
    </head>
    <body>
            <div class="box1">
                <div class="box2"></div>
            </div>
    </body>
    

    首先box2是第二层。

    此时box2位于box1下面,因为box1是第三层块级水平盒子。

    如果把transform注释解开,box2就位于box1上面,原因是此时box1触发了层叠,所以box1的background变成了第一层。

  3. inline的层叠等级比float高,可以理解为是因为文字内容的优先级高于图片内容。

  4. z-index为auto或0的情况,其实范围很广,不一定是说position,也可能是transform、opacity(当然他们都是默认为z-index: auto)。

    demo如下:

    <head>
        <style> 
            .box1 { 
                background-color:pink; 
                width: 100px; 
                height: 100px;
                transform: scale(1);
            }    /* 此时该div是普通元素,z-index无效 */
            .box2 { 
                position: absolute; 
                background-color: #abcdef;
                width: 50px;
                height: 50px;
            }
            .box3{
                transform: rotate(45deg);  
                background-color:antiquewhite;
                width: 60px;
                height: 60px;
            }
        </style>
    </head>
    <body>
            <div class="box1">
                <!--可以手动交换下面两行查看效果-->
                <div class="box2"></div>
                <div class="box3"></div>
            </div>
    </body>
    

BFC又是啥

块级格式化上下文,我理解成把一个元素和他的子元素一起分割出来形成一块渲染区域,不再影响他外面的元素(如清除浮动、阻止margin合并、包含浮动)。

两个注意点

  1. 每一个元素只能处于一个BFC中
  2. BFC只包含子元素

触发方式

  1. float的值不为none

  2. overflow的值为auto,scrollhidden

  3. display的值为table-cell, table-caption, inline-blocktableinline-tableflexinline-flexgridinline-grid中的任何一个。

    display:table会生成一个匿名的table-cell,这个匿名的table-cell产生了BFC。

  4. position的值不为relativestatic

  5. containlayoutcontentpaint

常见用法

  1. 清除浮动

    当img设置了float,可以让旁边的div形成一个新的BFC(给他设置overflow: hidden),阻止div中的子元素text和img相互影响。 image-20210629230639019.png image-20210629230659164.png

  2. 阻止margin合并

    处于同一个BFC的两个块级元素A和B,上下margin会合并。为了让他们之间不相互影响,可以通过给A或B的父级包一个新的BFC,让他们不处于同一个BFC下来解决。

    <head>
        <style> 
            .box1 { 
                background-color:pink; 
                width: 100px; 
                height: 100px;
            } 
            .box2 { 
                background-color: #abcdef;
                width: 50px;
                height: 50px;
                margin-bottom: 10px;
            }
            .box3{
                background-color:antiquewhite;
                margin-top: 10px;
                width: 60px;
                height: 60px;
            }
        </style>
    </head>
    <body>
            <div class="box1">
                <div class="box2"></div>
                <div style="overflow: hidden;"> <!--可以通过注释或解开这个div来查看效果-->
                     <div class="box3"></div>
                </div>
            </div>
    </body>
    
  3. 包含浮动元素

    新建一个BFC,划分一个范围,包含子元素的浮动盒子以免影响外面的元素。

    <head>
        <style> 
            .box1 { 
                background-color:pink; 
                width: 100px; 
                height: 100px;
            } 
            .box2 { 
                border: 1px solid black;
                /* overflow: hidden */ /**可以恢复这一行来查看效果**/
            }
            .box3{
                background-color:antiquewhite;
                width: 60px;
                height: 60px;
                float: left;
            }
        </style>
    </head>
    <body>
            <div class="box1">
                <div class="box2">
                    <div class="box3"></div>
                </div>
            </div>
    </body>
    

参考文章

www.zhangxinxu.com/wordpress/2…

juejin.cn/post/684490…

www.zhangxinxu.com/wordpress/2…