Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show an animation that is hidden behind a colored div using a "reveal" div on the surface

Tags:

html

css

Imagine that we have two layers of background.

  • The bottom layer is green <div class="green"></div>. For simplicity, let's assume it's just a color. But in my project, this layer contains a css animation.

  • And another layer of blue goes on top of it <div class="blue"></div>.

  • Now, I want to have another div that goes on top of both, and it reveals the green background (animation layer in my project).

The closest example I can think of is if you imagine a spotlight. Everything seems black, and the spotlight moves around and reveals the background.

Essentially, that's what I have:

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

It will look something like this. Just remember, the green layer is an animation in my project.

enter image description here

QUESTION: how can I complete the .reveal styles to achieve the above behavior.

  • First div - draws .green background (animation)
  • Second dv - draws .blue background goes on top of it
  • Third/Fourth/... divs - Goes on top of both, but it reveals whatever the background First div draws

Note: First and Second div covers 100% of the available width and height.

.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>

P.S. There is one approach I found that I did not like at all.

enter image description here

like image 556
Hafiz Temuri Avatar asked May 02 '20 00:05

Hafiz Temuri


People also ask

How do I make a Div reveal itself?

Add the class ‘targetDiv’ to the element that you want to reveal and the ID ‘divreveal1’ where the last part is the same as the ID used for the trigger Reply

How do I show / hide an element in a Div?

Add a Button Module to your page that you want to use to show / reveal the target element. Now add the element you want to show / hide. This can be a section, row or module. Go to the settings for the element, e.g. Related Post: Adding JavaScript / jQuery to Divi.

How do I make a Divi builder element displayed on the button?

Here are the steps to making a Divi Builder element (module, etc) displayed on the click of a button (and re-hidden if the button is clicked again). Add a Button Module to your page that you want to use to show / reveal the target element. Now add the element you want to show / hide. This can be a section, row or module.

How do I add a hidden element to a reveal button?

Give each new reveal button its own CSS class, for example "rv_button_2" for the second reveal button, "rv_button_3" for the third and so on. Give each new hidden element its own CSS class, for example "rv_element rv_element_2" for the second element, "rv_element rv_element_3" for the third, and so on.


2 Answers

Use mask to create a hole and no need for the reveal div. You can later change the size and position to have the animation you want:

.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>

You can also add as many mask as you want:

.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>
like image 155
Temani Afif Avatar answered Oct 23 '22 00:10

Temani Afif


A techhnique that will work, with an even simpler layout, is 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>

Also, you have a posibility to achieve this using blending.

The main disadvantage is that this uses hard-light , son the colors used in layer2 are limited to having 0 or 255 for the primary colors (red blue and green).

It will work for pure red (255, 0,0), green (0, 255, 0), blue (0, 0, 255), and also (255, 255, 0), (255, 0, 255), (0, 255, 255)

But it has the advantage that you can set severial divs to act as 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>

This will work also for multiple divs:

.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>
like image 43
vals Avatar answered Oct 23 '22 01:10

vals