如何使用表面上的“显示” div 显示隐藏在彩色 div 后面的动画
Posted
技术标签:
【中文标题】如何使用表面上的“显示” div 显示隐藏在彩色 div 后面的动画【英文标题】:How to show an animation that is hidden behind a colored div using a "reveal" div on the surface 【发布时间】:2020-05-02 00:24:28 【问题描述】:假设我们有两层背景。
底层为绿色<div class="green"></div>
。为简单起见,我们假设它只是一种颜色。但在我的项目中,这一层包含一个css 动画。
上面还有一层蓝色<div class="blue"></div>
。
现在,我想要另一个 div
放在两者之上,它显示绿色背景(我项目中的动画层)。
我能想到的最接近的例子是如果你想象一个聚光灯。一切似乎都是黑色的,聚光灯四处移动,露出背景。
基本上,这就是我所拥有的:
<div class="green">
<div class="blue">
<div class="reveal"></div>
</div>
</div>
它看起来像这样。请记住,绿色层是我项目中的动画。
问题:如何完成.reveal
样式以实现上述行为。
.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>
附:我发现有一种方法我根本不喜欢。
【问题讨论】:
我可以把<div class="reveal">
放在<div class="blue">
之外吗?
您的问题到底是什么?
@Dekel 我不确定如何完成.reveal
的样式以实现上述行为。我编辑了 OP
@MARSHMALLOW 我想是的,只要我有两层完整的背景。我计划在我的项目中为green
背景设置动画。
@Dekel 刚刚更新
【参考方案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>
【讨论】:
以上是关于如何使用表面上的“显示” div 显示隐藏在彩色 div 后面的动画的主要内容,如果未能解决你的问题,请参考以下文章