【问题标题】:How to show an animation that is hidden behind a colored div using a "reveal" div on the surface如何使用表面上的“显示” div 显示隐藏在彩色 div 后面的动画
【发布时间】:2026-01-08 08:15:02
【问题描述】:

假设我们有两层背景。

  • 底层为绿色<div class="green"></div>。为简单起见,我们假设它只是一种颜色。但在我的项目中,这一层包含一个css 动画

  • 上面还有一层蓝色<div class="blue"></div>

  • 现在,我想要另一个 div 放在两者之上,它显示绿色背景(我项目中的动画层)。

我能想到的最接近的例子是如果你想象一个聚光灯。一切似乎都是黑色的,聚光灯四处移动,露出背景。

基本上,这就是我所拥有的:

<div class="green">
    <div class="blue">
        <div class="reveal"></div>
    </div>
</div> 

它看起来像这样。请记住,绿色层是我项目中的动画。

问题:如何完成.reveal 样式以实现上述行为。

  • 第一个 div - 绘制 .green 背景(动画)
  • 第二个 dv - 在上面绘制 .blue 背景
  • Third/Fourth/... div - 位于两者之上,但它揭示了 First div 绘制的任何背景

注意:第一个和第二个 div 覆盖了100% 的可用宽度和高度。

.green {
    background-color: #159c82;
    width: 100vw;
    height: 100vh;
}

.blue {
    background-color: #1b4287;
    // I could change this to a sibling div and use,
    // position: absolute; but that seems unnecessary
    width: 100%;
    height: 100%;
}

.reveal {
    margin-top: 10px;
    margin-left: 10px;
    width: 200px;
    height: 50px;
    // not sure what else to put here to make it work
}

<div class="green">
    <div class="blue">
        <div class="reveal"></div>
    </div>
</div>

附:我发现有一种方法我根本不喜欢。

【问题讨论】:

  • 我可以把&lt;div class="reveal"&gt;放在&lt;div class="blue"&gt;之外吗?
  • 您的问题到底是什么?
  • @Dekel 我不确定如何完成.reveal 的样式以实现上述行为。我编辑了 OP
  • @MARSHMALLOW 我想是的,只要我有两层完整的背景。我计划在我的项目中为green 背景设置动画。
  • @Dekel 刚刚更新

标签: html css


【解决方案1】:

使用蒙版创建一个洞,不需要显示 div。您可以稍后更改大小和位置以获得所需的动画:

.green {
  background: linear-gradient(45deg,#159c82,red);
  height: 100vh;
}

.blue {
  background:#1b4287;
  height: 100%;
  -webkit-mask:
    /* you adjust this */
    linear-gradient(#fff,#fff) 
     50px 50px/ /*left top*/
     200px 20px, /*width height*/
    /**/
    linear-gradient(#fff,#fff); 
  -webkit-mask-repeat:no-repeat;    
  -webkit-mask-composite: destination-out;
  
  mask:
    /* you adjust this */
    linear-gradient(#fff,#fff) 
     50px 50px/ /*left top*/
     200px 20px, /*width height*/
    /**/
    linear-gradient(#fff,#fff);
  mask-repeat:no-repeat;    
  mask-composite:exclude;
  transition:.5s;
}
.blue:hover {
  -webkit-mask-position:100px 100px,0 0;
          mask-position:100px 150px,0 0;
  -webkit-mask-size:300px 50px,auto;
          mask-size:300px 50px,auto;
}

body {
  margin: 0;
}
<div class="green">
  <div class="blue">
  </div>
</div>

您还可以根据需要添加任意数量的掩码:

.green {
  background: url(https://picsum.photos/id/1018/800/800) center/cover;
  height: 100vh;
}

.blue {
  background:#1b4287;
  height: 100%;
  -webkit-mask:
    /* 3rd mask */
    radial-gradient(farthest-side,#fff 99%,transparent) 
     top 50px right 50px/ 
     100px 100px,
    /**/
    /* 2nd mask */
    linear-gradient(#fff,#fff) 
     bottom 50px right 50px/ 
     300px 20px,
    /**/
    /* 1st mask */
    linear-gradient(#fff,#fff) 
     50px 50px/ 
     200px 20px,
    /**/
    linear-gradient(#fff,#fff);
  -webkit-mask-repeat:no-repeat;    
  -webkit-mask-composite: destination-out;
  
  mask:
    /* 3rd mask */
    radial-gradient(farthest-side,#fff 99%,transparent) 
     top 50px right 50px/ 
     100px 100px,
    /**/
    /* 2nd mask */
    linear-gradient(#fff,#fff) 
     bottom 50px right 50px/ 
     300px 20px,
    /**/
    /* 1st mask */
    linear-gradient(#fff,#fff) 
     50px 50px/ 
     200px 20px,
    /**/
    linear-gradient(#fff,#fff);
  mask-repeat:no-repeat;    
  mask-composite:exclude;
  transition:.5s;
}
.blue:hover {
  -webkit-mask-position:
            100px 100px,
            bottom 100px left 50px,
            top 50px right 50px,
            0 0;
          mask-position:
            100px 100px,
            bottom 100px left 50px,
            top 50px right 50px,
            0 0;
  -webkit-mask-size:
            150px 150px,
            50px 50px,
            300px 50px,
            auto;
          mask-size:
            150px 150px,
            50px 50px,
            300px 50px,
            auto;
}

body {
  margin: 0;
}
<div class="green">
  <div class="blue">
  </div>
</div>

【讨论】:

    【解决方案2】:

    box-shadow 是一种行之有效且布局更简单的技术

    .layer1 {
      width: 100%;
      height: 100%;
      position: absolute;
      background-image: linear-gradient(yellow, blue);
      background-size: 200% 200%;
      animation: bkg 2s infinite alternate;
      background-origin: padding-box;
    }
    
    .layer2 {
      width: 200px;
      height: 200px;
      position: absolute;
      background: transparent;
      border-radius: 30px;
      left: 20px;
      top: 40px;
      box-shadow: 0px 0px 0px 10000px blue;
    }
    
    
    @keyframes bkg {
      from {
        background-position: 0 0;
      }
      to {
        background-position: 100% 100%
      }
    }
    <div class="layer1"></div>
    <div class="layer2">
    </div>

    此外,您还可以使用混合来实现此目的。

    主要缺点是它使用 hard-light ,因此 layer2 中使用的颜色仅限于具有 0 或 255 的原色(红蓝和绿色)。

    它适用于纯红色 (255, 0,0)、绿色 (0, 255, 0)、蓝色 (0, 0, 255),也适用于 (255, 255, 0)、(255, 0, 255), (0, 255, 255)

    但是它的好处是可以设置多个div来充当windows

    .layer1 {
      width: 100%;
      height: 100%;
      position: absolute;
      background-image: linear-gradient(yellow, blue);
      background-size: 200% 200%;
      animation: bkg 2s infinite alternate;
      background-origin: padding-box;
    }
    
    .layer2 {
      width: 100%;
      height: 100%;
      position: absolute;
      background: rgba(0, 255, 0);
      mix-blend-mode: hard-light;
    }
    
    .layer3 {
      width: 200px;
      height: 200px;
      position: absolute;
      background: grey;
      border-radius: 30px;
      left: 20px;
      top: 40px;
    }
    
    @keyframes bkg {
      from {
        background-position: 0 0;
      }
      to {
        background-position: 100% 100%
      }
    }
    <div class="layer1"></div>
    <div class="layer2">
      <div class="layer3"></div>
    </div>

    这也适用于多个 div:

    .layer1 {
      width: 100%;
      height: 100%;
      position: absolute;
      background-image: linear-gradient(yellow, blue);
      background-size: 200% 200%;
      animation: bkg 2s infinite alternate;
      background-origin: padding-box;
    }
    
    .layer2 {
      width: 100%;
      height: 100%;
      position: absolute;
      background: rgba(0, 255, 0);
      mix-blend-mode: hard-light;
    }
    
    .layer3 {
      width: 200px;
      height: 200px;
      position: absolute;
      background: grey;
      border-radius: 30px;
      left: 20px;
      top: 40px;
    }
    
    .layer3:nth-child(2) {
      left: 120px;
      top: 80px;
    }
    
    @keyframes bkg {
      from {
        background-position: 0 0;
      }
      to {
        background-position: 100% 100%
      }
    }
    <div class="layer1"></div>
    <div class="layer2">
      <div class="layer3"></div>
      <div class="layer3"></div>
    </div>

    【讨论】:

      【解决方案3】:

      你想只把显示 div 放在这个位置,还是从底层显示绿色?

      仅对于位置,您可以在蓝色 div 中添加实际位置,在显示 div 中添加绝对位置以及顶部和左侧值。

      .green {
          background-color: #159c82;
          width: 100vw;
          height: 100vh;
      }
      
      .blue {
          background-color: #1b4287;
          width: 100%;
          height: 100%;
      
          position: relative;
      }
      
      .reveal {
          position: absolute;
          top: 10px;
          left: 10px;
      
          width: 200px;
          height: 50px;
      }
      

      【讨论】:

      • 这不是我想要的,.reveal 需要显示底部背景。我更新了问题,希望更有意义。
      • 我想从底层显示绿色。
      【解决方案4】:

      如果我理解正确,您可能应该使用 css 变量。 https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties

      编辑您的示例,我们得到以下内容。

      :root {
        --bottom-layer-color: #159c82
      }
      
      .green {
        background-color: var(--bottom-layer-color);
        width: 100vw;
        height: 100vh;
      }
      
      .blue {
        background-color: #1b4287;
        width: 100%;
        height: 100%;
      }
      
      .reveal {
        margin-top: 10px;
        margin-left: 10px;
        width: 200px;
        height: 50px;
        background-color: var(--bottom-layer-color)
      }
      
      <div class="green">
        <div class="blue">
          <div class="reveal"></div>
        </div>
      </div>
      

      干杯,

      用css改变颜色:

      /* Use a later css file to redeclare the root variable,    */
      /* this will override previously declared css. */
      /* https://css-tricks.com/precedence-css-order-css-matters/ */
      :root {
        --bottom-layer-color: powderblue
      }
      

      用javascript改变颜色:

      const eStyle = document.documentElement.style
      eStyle.setProperty('--top-bar-height', '263px');
      

      你可以用 css 变量改变很多东西。不仅仅是背景颜色。

      例如

      root: {
        --bottom-layer-color: #159c82
        --bottom-layer-radius: 50%;
        /* this would make the bottom layer a circle. And reaveal a circle. */
      }
      
      .green {
        background-color: var(--bottom-layer-color)
        border-radius: var(--bottom-layer-color)
        width: 100vw;
        height: 100vh;
      }
      
      .reveal {
        background-color: var(--bottom-layer-color)
        border-radius: var(--bottom-layer-color)
      }
      
      /* Set --bottom-layer-radius back to 0 to make both items square again. */
      

      【讨论】:

      • 不,这对我不起作用。我在底层有一个动画。因此,它必须与底层完全相同。
      【解决方案5】:

      这是 CSS 中最简单的事情之一

      <Style>
      .blue {
      width: 100%;
      height: 300px;
      background-color: lightblue;
      }
      </style>
      <div class="blue">
      </div>
      

      【讨论】:

        最近更新 更多