You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现两个Div交集区域透明:穿透白色Div显示背景渐变

问题描述

我正在开发一个网站,页面背景设置为蓝色渐变效果。页面右上角有一个白色圆形Div,其上方放置了汉堡菜单的三条横向bar。我希望这些bar区域能够穿透白色圆形Div,显示出背后的背景渐变,同时bar本身保持黑色外观。以下是我的当前实现代码:

index.html

<!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" />
    <link href="https://fonts.googleapis.com/css2?family=Anonymous+Pro&family=Lato&family=Ubuntu+Mono&display=swap" rel="stylesheet" />
    <link rel="stylesheet" href="./style.css" />
    <script src="./app.js" defer></script>
    <title>lBark</title>
  </head>
  <body>
    <div id="burger-menu">
      <div class="circle"></div>
      <div class="menu">
        <div class="menu-bar"></div>
        <div class="menu-bar"></div>
        <div class="menu-bar"></div>
      </div>
    </div>
    <!-- <button style="position: absolute; left: 50%; top: 50%; width: 10vw; height: 10vh; cursor: none;" onclick="alert('hello')"></button> -->
    <img id="cursor" style="opacity: 0;" src="./img/Cursor.svg">
    <div style="width: 5vw; height: 10vh; background-color: red; position: absolute; left: 0; bottom: 0;"></div>
    <div style="width: 5vw; height: 10vh; background-color: green; position: absolute; left: 5vw; bottom: 0;"></div>
    <div style="width: 5vw; height: 10vh; background-color: blue; position: absolute; left: 10vw; bottom: 0;"></div>
    <p class="hero">Epicness</p>
  </body>
</html>

style.css

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  background-color: transparent;
}

html {
  font-size: 62.5%;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  /* cursor: none; */
  background: linear-gradient(
    135deg,
    rgba(95, 21, 242, 1) 0%,
    rgba(28, 127, 238, 1) 25%,
    rgba(47, 201, 226, 1) 50%,
    rgba(63, 218, 216, 1) 75%,
    rgba(79, 220, 74, 1) 100%
  );
}

#cursor {
  position: absolute;
  transform: translate(-50%, -50%);
  mix-blend-mode: difference;
  background-color: transparent;
  pointer-events: none;
  width: 3rem;
  height: auto;
  transition: opacity ease-in-out 0.3s, width ease-in-out 0.1s;
  z-index: 1;
}

.hero {
  font-size: 15rem;
  font-family: 'Anonymous Pro';
  font-weight: bold;
  color: white;
  background-color: transparent;
}

#burger-menu {
  position: absolute;
  top: 0;
  right: 0;
  width: 12vw;
  height: 12vw;
  background-color: transparent;
}

#burger-menu .circle {
  position: absolute;
  width: 100%;
  height: 100%;
  /* background: radial-gradient(circle at center, rgba(255,255,255,0.7) 30%,rgba(255,255,255,0) 70%); */
  background-color: white;
  border-radius: 50%;
  transform: translate(40%, -40%);
}

#burger-menu .menu {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-direction: column;
  position: absolute;
  top: 10%;
  right: 10%;
  width: 20%;
  height: 16%;
}

#burger-menu .menu-bar {
  width: 100%;
  height: 15%;
  border-radius: 3rem;
  background-color: black;
}

app.js

// Variables {{{
let dotPositions = [];
let cursorX = 0;
let cursorY = 0;
// }}}

// Cursor Control {{{
{
  const cursor = document.querySelector("#cursor");
  let firstCursorMove = true;

  document.onmousemove = (event) => {
    if (firstCursorMove) {
      firstCursorMove = false;
      cursor.style.opacity = 1;
      event
    }

    cursorX = event.clientX;
    cursorY = event.clientY;

    cursor.style.left = cursorX + "px";
    cursor.style.top = cursorY + "px";
  };

  // document.onmousedown = () => {
  //   if (!firstCursorMove)
  //   {
  //     expandingDot();
  //   }
  // }

  document.querySelectorAll("button").forEach(button => {
    button.addEventListener("mouseenter", () => {
      cursor.style.width = "5rem";
    });

    button.addEventListener("mouseleave", () => {
      cursor.style.width = "";
    });
  })
}
// }}}

// Background {{{
{
  // const canvas = document.querySelector("#background-canvas");
  // const context = canvas.getContext("2d");
  // // Depending on distance from top left decrease dot size
  // // When scrolling dots move towards top left and change size
  // // When link clicked black dot at link which expands
  // // Splash effect on click
  // canvas.width = window.innerWidth;
  // canvas.height = window.innerHeight;

  function expandingDot() {
    let expandingCircle = document.createElement("div");
    document.body.appendChild(expandingCircle);
    expandingCircle.style.cssText = `position: absolute; left: ${cursorX}px; top: ${cursorY}px; transform: translate(-50%, -50%) scale(0); border-radius: 50%; background-color: black; transition: transform 1s ease-in-out; will-change: transform;`;

    setTimeout(() => {
      if (window.innerHeight > window.innerWidth) {
        expandingCircle.style.width = "250vh";
        expandingCircle.style.height = "250vh";
      }

      else {
        expandingCircle.style.width = "250vw";
        expandingCircle.style.height = "250vw";
      }

      expandingCircle.style.transform = "translate(-50%, -50%) scale(1)";
    }, 0);
  }
}

function randomNumber(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}
// }}}

Cursor.svg

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="30" height="30" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
    <path d="M10,0C15.519,0 20,4.481 20,10C20,15.519 15.519,20 10,20C4.481,20 0,15.519 0,10C0,4.481 4.481,0 10,0ZM10,5C12.76,5 15,7.24 15,10C15,12.76 12.76,15 10,15C7.24,15 5,12.76 5,10C5,7.24 7.24,5 10,5Z" style="fill:white;"/>
    <circle cx="10" cy="10" r="3" style="fill:white;"/>
</svg>
解决方案

要实现bar穿透白色圆形显示背景渐变的效果,推荐两种简洁的CSS方案:

方案一:混合模式实现(推荐)

通过mix-blend-mode让白色圆形与背景混合,同时让黑色bar抵消白色区域,透出背景渐变:

修改style.css中.circle和.menu-bar的样式:

#burger-menu .circle {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: white;
  border-radius: 50%;
  transform: translate(40%, -40%);
  /* 白色与背景混合,弱化白色覆盖 */
  mix-blend-mode: screen;
}

#burger-menu .menu-bar {
  width: 100%;
  height: 15%;
  border-radius: 3rem;
  background-color: black;
  /* 黑色与下方白色混合,穿透显示背景 */
  mix-blend-mode: multiply;
}

原理

  • screen模式下,白色会与背景渐变混合,降低白色的不透明度;
  • multiply模式下,黑色bar会与下方的白色区域混合,完全抵消白色,透出背后的背景渐变;
  • 该方案无需精确计算位置,适配性强,代码改动最小。

方案二:遮罩镂空实现

通过CSS mask属性在白色圆形上创建与bar对应的镂空区域,直接透出背景:

修改style.css中.circle的样式:

#burger-menu .circle {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: white;
  border-radius: 50%;
  transform: translate(40%, -40%);
  /* 创建三个与bar位置匹配的镂空区域 */
  mask: 
    linear-gradient(black, black) no-repeat 80% 10% / 20% 15%,
    linear-gradient(black, black) no-repeat 80% 58% / 20% 15%,
    linear-gradient(black, black) no-repeat 80% 106% / 20% 15%,
    linear-gradient(black, black);
  /* 排除镂空区域,显示背景 */
  mask-composite: exclude;
}

原理

  • mask属性通过多个线性渐变创建三个与bar尺寸、位置一致的黑色区域;
  • mask-composite: exclude将这些区域从白色圆形中排除,形成镂空,背景渐变自然透出;
  • 该方案效果精准,但需要根据bar的布局调整mask的位置和尺寸参数。

完整修改后的style.css

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  background-color: transparent;
}

html {
  font-size: 62.5%;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  /* cursor: none; */
  background: linear-gradient(
    135deg,
    rgba(95, 21, 242, 1) 0%,
    rgba(28, 127, 238, 1) 25%,
    rgba(47, 201, 226, 1) 50%,
    rgba(63, 218, 216, 1) 75%,
    rgba(79, 220, 74, 1) 100%
  );
}

#cursor {
  position: absolute;
  transform: translate(-50%, -50%);
  mix-blend-mode: difference;
  background-color: transparent;
  pointer-events: none;
  width: 3rem;
  height: auto;
  transition: opacity ease-in-out 0.3s, width ease-in-out 0.1s;
  z-index: 1;
}

.hero {
  font-size: 15rem;
  font-family: 'Anonymous Pro';
  font-weight: bold;
  color: white;
  background-color: transparent;
}

#burger-menu {
  position: absolute;
  top: 0;
  right: 0;
  width: 12vw;
  height: 12vw;
  background-color: transparent;
}

#burger-menu .circle {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: white;
  border-radius: 50%;
  transform: translate(40%, -40%);
  mix-blend-mode: screen;
}

#burger-menu .menu {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-direction: column;
  position: absolute;
  top: 10%;
  right: 10%;
  width: 20%;
  height: 16%;
}

#burger-menu .menu-bar {
  width: 100%;
  height: 15%;
  border-radius: 3rem;
  background-color: black;
  mix-blend-mode: multiply;
}

内容的提问来源于stack exchange,提问作者Brumus14

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 05:14:54