Code前端首页关于Code前端联系我们

通过这篇文章了解 CSS 级联上下文、级联级别、级联顺序和 z-index

terry 2年前 (2023-09-27) 阅读数 95 #数据结构与算法

之前因为不经常使用z-index,所以对 CSS 的理解比较片面这个 CSS 属性。我一直认为z-index用于描述和定义屏幕上元素Z轴的堆叠顺序。 z-index值越大,在Z轴上的位置就越高,即离屏幕观察者越近。最后我发现这个理解有很大的问题:

  1. 首先,z-index对任何元素都没有影响。 仅对 定位元素(定义 位置 属性且具有 ❝ 以外的值的元素)有影响。
  2. 要确定Z 轴 上元素的堆叠顺序,不仅仅是直接比较z 索引 值。这个堆叠顺序实际上是由元素的决定的。 堆栈上下文和堆栈级别一起确定。
CSS层叠上下文、层叠等级、层叠顺序、z-index一文搞懂

如果你想完全理解一个东西,你必须首先理解它是什么,即它的定义。首先我们看一下上面的Stack ContextStack Level,以及❀❀是什么,定义太抽象了。后面我会用一个具体的比喻让大家明白它们是什么以及它们之间是如何联系的。

什么是“堆栈上下文”

堆栈上下文是HTML中的一个三维概念。 CSS2.1规范中,每个盒子模型的位置都是三维的,分别是平面画布上的X轴Y轴和,以及轴 代表级联。 。正常情况下,元素沿着X轴Y轴平铺在页面上,我们不知道它们在Z轴上的级联关系。当元素堆叠起来时,你可能会发现一个元素可以覆盖另一个元素,或者被另一个元素覆盖。

如果一个元素包含堆叠上下文(即它是堆叠上下文元素),我们可以理解为该元素是Z轴上的“父元素”,最终的表现是它离屏幕观看者更近。

具体比喻:你可以将普遍上下文元素理解为这个元素成为官方,而其他非级联上下文元素可以理解为普通人。所有“官方物品”的级别都高于常规物品,这意味着这些物品在 Z 轴 上更高,并且更靠近观察者。

什么是“稳定级别”

那么,堆叠级别指的是什么?堆栈级别(stack level,也称“堆栈级别”/“堆栈级别”)

  • 在同一个堆栈上下文中,描述和定义了堆栈上下文元素在堆栈上下文中在Z 轴上的位置 上下顺序。
  • 在其他普通元素中,描述并定义了这些普通元素在 Z 轴 上的上下顺序。

说到这里,很多人可能会有疑问。无论是在堆叠上下文中还是在常规元素中,堆叠级别都表示 Z 轴 上元素的上下顺序。那么只要说它描述了定义就足够了。如果所有元素在Z 轴 上按上下顺序排列就可以了!为什么要分开描述呢?

为了说明原因,我们举个例子:

具体比喻:前面我们提到过,级联上下文中的元素就像是充当公务员的元素,其级别自然要高于普通元素。再想一想,假设甲官员是省级领导。他手下有一个秘书a-1,家里有一个保姆a-2。另一位官员B是县长。他手下有一个秘书b-1,家里有一个保姆b-2。虽然a-1和b-1都是秘书,但是你觉得省领导的秘书和县领导的秘书有什么可比性吗?就连保姆A-2的评价也比秘书B-1高很多。谁大谁小、谁高谁矮都是一目了然的,所以根本没有必要比较。只有比较A的下属的a-1和a-2与B的下属的b-1和b-2的相对大小才有意义。

类比“级联上下文”和“级联层级”,我们得出结论:

  1. 普通元素的堆叠层级首先由其所在的堆叠上下文决定。
  2. 比较堆叠级别仅在当前堆叠上下文元素内才有意义。比较不同堆叠上下文中的堆叠级别是没有意义的。

如何生成“级联上下文”

前面说了这么多,我知道了“级联上下文”和“级联级别”,但是有一个最关键的问题:如何生成级联上下文?如何使一个元素成为普遍的上下文元素?

实际上,普遍上下文最初是使用一些特定的 CSS 属性创建的。一般有三种方法:

  1. HTML中的根元素 j本身有一个堆叠上下文,称为“根堆叠上下文”。
  2. 常见元素将位置属性设置为静态❙值并将值属性设置为特定值以生成普遍上下文。
  3. CSS3 中的新属性还可以生成级联上下文。

至此我们终于可以写代码了。我们用代码来证实上面的结论:

栗子1: 有两个div,p.a和p.b包裹在一个div中,p.c包裹在另一个box中和z-索引

.a、.b、.c 的属性

<style>
  div {  
    position: relative;  
    width: 100px;  
    height: 100px;  
  }  
  p {  
    position: absolute;  
    font-size: 20px;  
    width: 100px;  
    height: 100px;  
  }  
  .a {  
    background-color: blue;  
    z-index: 1;  
  }  
  .b {  
    background-color: green;  
    z-index: 2;  
    top: 20px;  
    left: 20px;  
  }  
  .c {  
    background-color: red;  
    z-index: 3;  
    top: -20px;  
    left: 40px;  
  }
</style>

<body>  
  <div>  
    <p class="a">a</p>  
    <p class="b">b</p>  
  </div> 

  <div>  
    <p class="c">c</p>  
  </div>  
</body> 
复制代码

。效果: CSS层叠上下文、层叠等级、层叠顺序、z-index一文搞懂

因为 p.a, p.b, p.c 的三个父元素 div 没有设置z-index,所以不会生成级联上下文,所以.a,.b,.c都是在中,由标签生成的“根级联上下文”属于相同的普遍上下文。此时,较高的 z-index 值将位于顶部。 栗子2: 有两个div,p.a,p.b包裹在一个div中,p.c包裹在另一个box中,有两个div还有.a,.b,.b,. time 设置 位置z-index

<style>
  div {
    width: 100px;
    height: 100px;
    position: relative;
  }
  .box1 {
    z-index: 2;
  }
  .box2 {
    z-index: 1;
  }
  p {
    position: absolute;
    font-size: 20px;
    width: 100px;
    height: 100px;
  }
  .a {
    background-color: blue;
    z-index: 100;
  }
  .b {
    background-color: green;
    top: 20px;
    left: 20px;
    z-index: 200;
  }
  .c {
    background-color: red;
    top: -20px;
    left: 40px;
    z-index: 9999;
  }
</style>

<body>
  <div class="box1">
    <p class="a">a</p>
    <p class="b">b</p>
  </div>

  <div class="box2">
    <p class="c">c</p>
  </div>
</body>
复制代码

效果:CSS层叠上下文、层叠等级、层叠顺序、z-index一文搞懂

即使元素是,我们也会发布。 z-index 值为 9999,远大于p.a 和 ❀♾ 和 的 z-index 值❀,但是。的 p.c

生成的级联上下文的 z-index 值为 1,因此 始终位于 c 之间。 p.a

p.b 下面。同时,如果我们只改变p.az-index值,p.b❝就是元素 box1 是在级联上下文中生成的,因此 z-index 值较大的位于顶部。

什么是“堆栈顺序”

说完“堆栈上下文”和“堆栈级别”,我们再来谈谈“堆栈顺序”。 “堆叠顺序”是指堆叠的项目按照特定的排序规则垂直显示在Z 轴 上。 可见,前面提到的“级联上下文”和“级联层次”是概念,而这里的“级联顺序”是一个规则。 CSS层叠上下文、层叠等级、层叠顺序、z-index一文搞懂

不管CSS3,当元素级联时,总体顺序遵循上述规则。 这里值得注意的是:

  1. 左上角“层叠上下文背景/边框”指的是层叠上下文元素的背景和边框。
  2. inline/inline-block元素的堆栈顺序高于block(块级)/floatings(浮动s)。
  3. 基本上考虑堆叠顺序,z-index: autoz-index: 0处于同一级别,但两个属性不同。

关于上面的第2点,为什么inline/inline-block元素的堆叠顺序高于block(块级/)元素?这个你可以考虑一下!其实很简单。像边框/背景之类的东西是装饰元素的属性。浮动元素和块级元素通常用于页面布局。网页设计之初最重要的是文字内容,因此在发生级联时会优先考虑文字内容。显示文本内容以确保其不被覆盖。

你想要的日常

上面说了这么多,你可能还是有点困惑。概念性规则这么多,这里是最实用的一个。有没有一个“套路”可以清楚地判断元素堆叠时谁在上面、谁在下面?答案是——肯定! ?图片)。 1.2 如果两个元素不在同一个堆叠上下文中,首先比较它们所在的堆叠上下文的堆叠级别。 2. 当两个元素的堆叠级别相同且堆叠顺序相同时,后一个元素的堆叠级别为位于 DOM 结构中前一个元素之上。

光说不练

对于技术学习来说,代码查看是最直观、容易理解的方式之一。废话不多说,我们直接上代码吧。让我们用下面的“栗子”来进一步证实和理解上面的结论。

栗子3:

<style>
  .box1, .box2 {
    position: relative;
    z-index: auto;
  }
  .child1 {
    width: 200px;
    height: 100px;
    background: #168bf5;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
  }
  .child2 {
    width: 100px;
    height: 200px;
    background: #32c292;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
  }
</style>
</head>

<body>
  <div class="box1">
    <div class="child1"></div>
  </div>

  <div class="box2">
    <div class="child2"></div>
  </div>
</body>
复制代码

效果:CSS层叠上下文、层叠等级、层叠顺序、z-index一文搞懂

描述:.box1/.box2虽然位置: z-index: auto 至于,它是两个 div 仍然是常见元素,不会生成级联上下文。因此,child1/.child2属于元素的“根堆叠上下文”。这个时候,如果z-index就值很多钱了,在上面的 栗子 4:

对于栗子 1 中的 CSS 代码,我们只需将 / 的 z-index 属性值更改为 ❀❀/。 值为0

,其余不变。 明 效果:: 解释:此时,我们发现z-index.box1/的属性值只有z-index属性值。如果值为 0

,则最终结果恰恰相反。此时,.child2覆盖.child1。是什么原因?非常简单:因为设置 z-index: 0 后,.box1/.box2 会生成自己的级联上下文。此时需要比较 .child1/.child2的层叠关系完全是由父元素.box1/.box2的重叠关系决定的。然而,.box1/.box2z-index值都是0并且它们都是块级元素(因此它们的堆栈是相同的)。在这种情况下,在 DOM 结构中,它覆盖了 之后的前一个 ,然后是 .child2❀。

CSS3中的属性对级联上下文的影响

CSS3中有很多新属性,其中一些属性对级联上下文也有很大的影响。如下:

  1. 父元素的display属性值为flex|inline-flex,子元素的z-index❀值不是❀。该元素是普遍存在的上下文元素; 不透明度元素的
  2. 属性值不是1变换
  3. 元素的属性值不是
  4. 属性 e
正常`; filter元素的

  • 属性值不是none
  • 的元素隔离的属性值为isolate
  • will-change指定的属性值是以上之一; -webkit-overflow-scrolling到
  • 元素属性值设置为touch
  • 在CSS3中,如果元素属性满足上述条件之一,就会生成级联上下文。我们用第1条来简单解释一下。

    栗子5:

    <style>
      .box {
      }
      .parent {
        width: 200px;
        height: 100px;
        background: #168bf5;
        /* 虽然设置了z-index,但是没有设置position,z-index无效,.parent还是普通元素,没有产生层叠上下文 */
        z-index: 1;
      }
      .child {
        width: 100px;
        height: 200px;
        background: #32d19c;
        position: relative;
        z-index: -1;
      }
    </style>
    </head>
    
    <body>
      <div class="box">
        <div class="parent">
          parent
          <div class="child">child</div>
        </div>
      </div>
    </body>
    复制代码

    效果:CSS层叠上下文、层叠等级、层叠顺序、z-index一文搞懂

    描述:我们发现.child♽被覆盖。按照“套路”分析:.parent虽然设置了z-index属性值但没有设置位置,z-index 是无效。因此不会生成级联上下文,并且 .parent 仍然是正常的块级元素。此时,在栈顺序规则中,z-index值小于0.child将被普通的块级元素替换。家长优先栗子6:

    对于上面的栗子,我们只改变.box的属性并设置显示:flex,其他属性和DOM结构保持不变。

    版权声明

    本文仅代表作者观点,不代表Code前端网立场。
    本文系作者Code前端网发表,如需转载,请注明页面地址。

    热门