simplify the life

由 Sweep To Right 动效引发的对 z-index 的再度学习

z-index MDNHover.css

对于一个已经定位的盒子(即其 position 属性值不是 static),z-index 属性指定:

  1. 盒子在当前堆叠上下文中的堆叠层级
  2. 盒子是否创建一个本地堆叠上下文(后代元素的 z-indexes 不与此元素外部的 z-indexes 进行对比)

先看一个简单 demo:

简单 demo
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 100px;
      height: 100px;
    }

    .box1 {
      background-color: red;
    }

    .box2 {
      background-color: black;
      margin-top: -50px;
    }
  </style>
</head>
<body>
  <div class="box box1"></div>
  <div class="box box2"></div>
</body>
</html>

黑色 box 往上移 50px,且覆盖了红色一半,符合预期

尝试修改 .box1 样式如下,期望红色能覆盖黑色:

.box1 {
  background-color: red;
  z-index: 1;
}

没生效,需要记住很重要的一点,z-index 生效的元素 position 不能为默认的 static,设置成其他都可(简单点一般设置为 relative

.box1 {
  background-color: red;
  position: relative;
  z-index: 1;
}

番外:margin-top VS position:relative + top:

将 demo 稍加修改

demo1
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 100px;
      height: 100px;
      color: white;
    }

    .box1 {
      background-color: red;
    }

    .box2 {
      background-color: black;
      margin-top: -100px;
    }
  </style>
</head>
<body>
  <div class="box box1">hello</div>
  <div class="box box2"></div>
</body>
</html>

这个时候虽然 box2 遮住了 box1,但是 box1 的文字却没有被遮住

demo2
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 100px;
      height: 100px;
      color: white;
    }

    .box1 {
      background-color: red;
    }

    .box2 {
      background-color: black;
      position: relative;
      top: -100px;
    }
  </style>
</head>
<body>
  <div class="box box1">hello</div>
  <div class="box box2"></div>
</body>
</html>

demo2 用了 relative + top,box2 完全遮住了 box1。这里我的理解是设置 position: relative 后的移动,是完全的移动,而设置 margin,只会影响 background

再看一个简单 demo

简单 demo
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      display: inline-block;
      margin: 0.4em;
      padding: 1em;
      cursor: pointer;
      background: #e1e1e1;
      color: #666;
    }
  </style>
</head>
<body style="padding: 200px">
  <a class="container">
    <span>Hover me</span>
  </a>
</body>
</html>

效果也比较简单,container box 上面有个文字

但是我期望能在 container background 和文字之间,再放个 box,应该怎么操作?

margin-top 负值法依然可解

margin-top 负值法
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      display: inline-block;
      margin: 0.4em;
      padding: 1em;
      cursor: pointer;
      background: #e1e1e1;
      color: #666;
    }
    
    .box {
      width: 100px;
      height: 100px;
      background-color: red;
      margin-top: -20px;
    }
  </style>
</head>
<body style="padding: 200px">
  <a class="container">
    <span class="text">Hover me</span>
    <div class="box"></div>
  </a>
</body>
</html>

如果用 relative + top 呢?

首先如果对 .text 设置,是可行的

对 `.text` 设置 relative + bottom
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      display: inline-block;
      margin: 0.4em;
      padding: 1em;
      cursor: pointer;
      background: #e1e1e1;
      color: #666;
    }

    .text {
      position: relative;
      bottom: -20px;
    }
    
    .box {
      width: 100px;
      height: 100px;
      background-color: red;
    }
  </style>
</head>
<body style="padding: 200px">
  <a class="container">
    <span class="text">Hover me</span>
    <div class="box"></div>
  </a>
</body>
</html>

但是如果对 .box 设置 relative + 负 top 是不行的,因为后面的元素会覆盖前面的元素。因为 .text.box 其实是同级元素,那如果将 .box 元素设置为 z-index: -1 呢?答案是不行,整个都隐藏到最下面了,这是因为这个时候 .box 其实是会和 .container 甚至 html 根标签去比较层级。这个时候我们实际上期望 .container 容器内的元素是一体的,互相比较层级即可。我们给 .container 设置 z-index 属性,从而创建一个本地堆叠上下文(后代元素的 z-indexes 不与此元素外部的 z-indexes 进行对比)(当然设置其他属性也可,只要是能创建一个本地堆叠上下文均可)

给 `.container` 设置 z-index,从而创建一个本地堆叠上下文
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      display: inline-block;
      margin: 0.4em;
      padding: 1em;
      cursor: pointer;
      background: #e1e1e1;
      color: #666;
      position: relative;
      z-index: 0;
    }
    
    /* 可选设置,查看效果 */
    .text {
      position: relative;
      z-index: 0;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: red;
      position: relative;
      top: -20px;
      z-index: -1;
    }
  </style>
</head>
<body style="padding: 200px">
  <a class="container">
    <span class="text">Hover me</span>
    <div class="box"></div>
  </a>
</body>
</html>

优化下,将 .box::after 来实现

用 `::after` 实现
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      display: inline-block;
      margin: 0.4em;
      padding: 1em;
      cursor: pointer;
      background: #e1e1e1;
      color: #666;
      position: relative;
      z-index: 0;
    }
    
    .container::after {
      content: '';
      position: absolute;
      top: 0;
      right: 0;
      left: 0;
      bottom: 0;
      background-color: red;
      z-index: -1;
    }
  </style>
</head>
<body style="padding: 200px">
  <a class="container">
    Hover me
  </a>
</body>
</html>

再回来,其实 container 上加 z-index 是为了创建一个本地堆叠上下文,那么哪些属性可以创建本地堆叠上下文呢?参考 MDN(本地堆叠上下文,可以理解成这里面的 CSS 样式,和外面不会有关系,是自洽的,是解耦且独立的,在 CSS 视觉效果上展示,是一体的,是一起的)

比较常见的属性有:

  • positionabsolute 或者 relative 且设置 z-index 不为 auto
  • positionfixedsticky
  • opacity 小于 1
  • transform 不为 none

其实比较适合的属性是可以用 transform 来改写下

用 `transform` 改写
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .container {
      display: inline-block;
      margin: 0.4em;
      padding: 1em;
      cursor: pointer;
      background: #e1e1e1;
      color: #666;
      position: relative;
      /* 这里改动 */
      transform: translateZ(0);
    }
    
    .container::after {
      content: '';
      position: absolute;
      top: 0;
      right: 0;
      left: 0;
      bottom: 0;
      background-color: red;
      z-index: -1;
    }
  </style>
</head>
<body style="padding: 200px">
  <a class="container">
    Hover me
  </a>
</body>
</html>

posted on   lessfish  阅读(30)  评论(0编辑  收藏  举报

编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· Open-Sora 2.0 重磅开源!
历史上的今天:
2015-02-27 谈谈文字图片粒子化

导航

统计信息

点击右上角即可分享
微信分享提示