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

后端 未结 5 770
遇见更好的自我
遇见更好的自我 2020-12-18 01:09

Imagine that we have two layers of background.

  • The bottom layer is green

    . For simplicity, let\'s assum
相关标签:
5条回答
  • 2020-12-18 01:48

    This is one of the easiest things to do in CSS

    <Style>
    .blue {
    width: 100%;
    height: 300px;
    background-color: lightblue;
    }
    </style>
    <div class="blue">
    </div>
    
    0 讨论(0)
  • 2020-12-18 01:53

    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>

    0 讨论(0)
  • 2020-12-18 01:53

    If I understand you correctly you probably should use a css variable. https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties

    Editing your example we get the following.

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

    cheers,

    to change the color with 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
    }
    

    to change the color with javascript:

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

    You can change a lot of things with css variables. Not just background-colors.

    For instance

    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. */
    
    0 讨论(0)
  • 2020-12-18 02:04

    Do you want to put the reveal div in this postion only, or show the green color from the bottom layer?

    for only the positon you can add realtive position in your blue div and absolute position in your reveal div with top and left values.

    .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;
    }
    
    0 讨论(0)
  • 2020-12-18 02:09

    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>

    0 讨论(0)
提交回复
热议问题