总结CSS 实现新手引导效果的六种方式

前言

我们在平常做业务中,在功能变更,或者有大的改动时,经常会用到新手引导功能, 虽然有很多库可以使用, 但是有时候很简单的需求,没必要引入库, 本文用最简化代码,实现一下新手引导的遮罩部分, 主要是总结实现思想

主要难点就是, 一般遮罩层级要高于需要页面元素, 但是如何让页面高亮的元素突破遮罩的限制,是主要要解决的问题

以下的代码都将用最简化的方式实现, 写死元素的宽高, 主要重点是实现思想上:

方式一: 遮罩拼接

下面是 Antd Tour 组件的实现方式, 我们通过更改背景色,加以区分

从图中可以看出, 让元素突破遮罩的方式是,不突破, 改而让遮罩分成上下左右四块, 所以,第一种方式就是通过元素拼接遮罩, 实现代码如下:

html 复制代码
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .box {
      width: 100vw;
      height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .button {
      position: relative;
      z-index: 1;
      width: 400px;
      height: 100px;
    }

    .mask {
      width: 100vw;
      height: 100vh;
      position: absolute;
      inset: 0;
    }
    .mask .horizon {
      display: flex;
      justify-content: space-between;
    }

    .mask .horizon div {
      height: 100vh;
      width: calc(50vw - 200px);
      background-color: rgba(255, 0, 255, 0.3);
    }

    .mask .vertival {
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      position: absolute;
      top: 0;
      height: 100vh;
    }

    .mask .vertival div {
      width: 100vw;
      height: calc(50vh - 50px);
      background-color: rgba(255, 0, 0, 0.3);
    }
  </style>
  <body>
    <div class="box">
      <button class="button">新手指导</button>
    </div>
    <!-- 拼接实现遮罩 -->
    <div class="mask">
      <div class="horizon">
        <div></div>
        <div></div>
      </div>
      <div class="vertival">
        <div></div>
        <div></div>
      </div>
    </div>
  </body>

效果如下

方式二: 通过 border 的方式实现

上面代码太多了, 下面这种方式就简单太多了, 只要对当前元素通过伪元素的方式添加很宽很高的变宽即可

方式三: 通过给元素增加阴影

增加边框可以, 同理增加阴影肯定也可以了 , 代码与效果如下

方式四: 使用 css 的 clip-path

这种方式是通过裁剪的方式,将元素漏出来, 需要计算的点比较多, 大致就是计算一个回字

关于clip-path如果不熟,不知道怎么设置点的位置,可以在这个网站找思路,立马有很多预设的图型,我们只需要找到接近的那个。改一下数据即可 bennettfeely.com/clippy/

如图,我们发现这个形状,跟我们要设置遮罩的区域很像, 然后分析一下他的实现,顶点的顺序如下

位置3和位置8,两个点其实是重合起来了, 我把它分开,这样更容易理解执行顺序

明白了执行顺序,与实现原理, 代码实现就比较简单了

代码如下:

html 复制代码
  <style>
    .mask {
      position: absolute;
      inset: 0;
      background-color: rgb(210, 196, 196);
      clip-path: polygon(
        0% 0%,
        0% 100%,
        calc(50vw - 200px) 100%,
        calc(50vw - 200px) calc(50vh - 50px),
        calc(50vw + 200px) calc(50vh - 50px),
        calc(50vw + 200px) calc(50vh + 50px),
        calc(50vw - 200px) calc(50vh + 50px),
        calc(50vw - 200px) 100%,
        100% 100%,
        100% 0%
      );
    }
  </style>
  <body>
    <div class="box">
      <button class="button">新手指导</button>
    </div>
    <div class="mask"></div>
  </body>

方式五: 复制新元素放在遮罩位置

这种方式的实现就是不考虑元素与遮罩的关系, 直接copy一个新的元素,覆盖原有元素

核心代码如下:

html 复制代码
  <style>
   .mask {
      position: absolute;
      inset: 0;
      background-color: rgba(191, 223, 183, 0.5);
    }

    .mask .button {
      position: absolute;
      left: 50%;
      top: 50%;
      width: 400px;
      height: 100px;
      transform: translate(-50%, -50%);
      display: flex;
      justify-content: center;
      align-items: center;
    }
  </style>
  <body>
    <div class="box">
      <button class="button">新手指导</button>
    </div>
    <div class="mask">
      <button class="button">新手指导 copy</button>
    </div>
  </body>

实现方式六 canvas

这种其实不是纯css 实现了, 需要用到js, 思想就是画一个整屏的元素,然后在擦除元素位置, 核心代码如下

html 复制代码
<style>
    * {
      margin: 0;
      padding: 0;
    }
    .box {
      width: 100vw;
      height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .button {
      position: relative;
      z-index: 1;
      width: 400px;
      height: 100px;
    }

    canvas {
      position: absolute;
      top: 0;
    }
  </style>
  <body>
    <div class="box">
      <button class="button">新手指导</button>
    </div>
    <canvas id="canvas"></canvas>
  </body>

  <script>
    const button = document.querySelector(".button");
    const rect = button.getBoundingClientRect();
    const canvas = document.getElementById("canvas");
    const ctx = canvas.getContext("2d");
    canvas.setAttribute("width", window.innerWidth + "px");
    canvas.setAttribute("height", window.innerHeight + "px");
    ctx.fillStyle = "green";
    ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);
    ctx.clearRect(rect.left, rect.top, rect.width, rect.height);
  </script>

总结

本文主要实现新手引导中的遮罩与元素高亮如何处理, 分为六种实现方式, 主要学习其实现思想, 并在业务开发中, 选择最优解决方案

相关推荐
李小轰_Rex8 小时前
零开销 AI 数字人方案|Live2D 数字人驱动方案分享
前端·aigc
ModyQyW8 小时前
vite-plugin-uni-manifest 0.7:在 uni-app 读取之前生成
前端·uni-app
我命由我123458 小时前
Python 实用操作 - 文件操作(打开与关闭文件、读取文件、文件写入)
java·开发语言·前端·javascript·数据库·python·java-ee
修炼的dance9 小时前
批量转码前用 ffprobe 筛一遍,36 个文件能跳过 26 个
前端
费曼学习法9 小时前
从 0 到 1 上手 Super-Agent 架构:任务拆解、工具路由与失败回滚的三段实现
前端
2026小鱼AI9 小时前
当 LLM 生成的教学设计“不合格”:结构化校验、局部重生成与并发下的质量漂移
前端
疯华整猫9 小时前
借助 Trae 复刻百度网盘“无权限摇一摇”检测:Android 传感器 AI 辅助实战
前端
deli0079 小时前
流式输出为什么一段一段蹦?拆开 SSE 分块实测 20094 个乱码
前端
不一样的少年_9 小时前
为什么你写的 Agent 一报错就死循环?很多人都漏掉了这层“错误自救与熔断”机制
前端·后端·agent
857god9 小时前
做了个匿名聊天站,我把 7 个前端坑踩了一遍
前端