1

I found this codepen which I found really interesting, and am trying to make start on hover, and then stay open until you stop hovering, and it would then reverse and close. My issue is that first of all, it either does the animation on hover and then off hovers jumps straight to the start. Also when leaving hover midway through the animation, it simply jumps back to the start. Ive tried ".box:hover and box:hover:after" with no success. Any help would be appreciated!

The Pen
Disclaimer, this is not my pen, I found it and thought it was cool. Credit to the creator

 *{
      margin:0;
      padding:0;
    }
    .container {
      background: #f0f0f0;
      box-sizing: border-box;
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100vw;
      height: 100vh;
    }
    .box {
      border-radius: 20px;
      width: 60px;
      height: 60px;
      background: #f0f0f0;
      box-shadow:  0 0 0 #cccccc,
                   0 0 0 #ffffff,
                    10px 10px 10px #cccccc inset,
                    -10px -10px 10px #ffffff inset;
      animation: anime 3s cubic-bezier(0.16, 1, 0.3, 1) 1s infinite alternate;
      /* animation-fill-mode: forwards; */
    }

    @keyframes anime {
      0% {
        width: 60px;
        height: 60px;
        background: #f0f0f0;
        box-shadow:  0 0 0 #cccccc,
                     0 0 0 #ffffff,
                      10px 10px 10px #cccccc inset,
                      -10px -10px 10px #ffffff inset;
      }
      25% {
        width: 60px;
        height: 60px;
        background: #f8f8f8;
        box-shadow:  10px 10px 10px #cccccc,
                     10px 10px 10px #ffffff,
                     0 0 0 #cccccc inset,
                     0 0 0 #ffffff inset;
      }
      50% {
        width: 60px;
        height: 240px;
        background: #f8f8f8;
        box-shadow:  10px 10px 10px #cccccc,
                     10px 10px 10px #ffffff,
                     0 0 0 #cccccc inset,
                     0 0 0 #ffffff inset;
      }
      100% {
        width: 480px;
        height: 240px;
        background: #fafafa;
        box-shadow:  40px 40px 40px #cccccc,
                     0 0 0 #ffffff,
                     0 0 0 #cccccc inset,
                     2px 2px 2px #ffffff inset;
      }
<body>
    <div class="container">
      <div class="box"></div>
    </div>
</body>

2 Answers 2

0

Read about animation-play-state and look at the hidden snippet.
If you combine those two, you get what you need:

*{
margin:0;
padding:0;
}
.container {
background: #f0f0f0;
box-sizing: border-box;
display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
}
.box {
border-radius: 20px;
  width: 60px;
  height: 60px;
  background: #f0f0f0;
  box-shadow:  0 0 0 #cccccc,
             0 0 0 #ffffff,
              10px 10px 10px #cccccc inset,
              -10px -10px 10px #ffffff inset;
  animation: anime 3s cubic-bezier(0.16, 1, 0.3, 1) 1s infinite alternate;
  animation-play-state: paused; /* added */
  /* animation-fill-mode: forwards; */
}
body:hover .container .box {
  animation-play-state: paused; /* added */
}
body .container .box:hover {
  animation-play-state: running; /* added */
}
@keyframes anime {
  0% {
    width: 60px;
    height: 60px;
    background: #f0f0f0;
    box-shadow:  0 0 0 #cccccc,
                 0 0 0 #ffffff,
                  10px 10px 10px #cccccc inset,
                  -10px -10px 10px #ffffff inset;
  }
  25% {
    width: 60px;
    height: 60px;
    background: #f8f8f8;
    box-shadow:  10px 10px 10px #cccccc,
                 10px 10px 10px #ffffff,
                 0 0 0 #cccccc inset,
                 0 0 0 #ffffff inset;
  }
  50% {
    width: 60px;
    height: 240px;
    background: #f8f8f8;
    box-shadow:  10px 10px 10px #cccccc,
                 10px 10px 10px #ffffff,
                 0 0 0 #cccccc inset,
                 0 0 0 #ffffff inset;
  }
  100% {
    width: 480px;
    height: 240px;
    background: #fafafa;
    box-shadow:  40px 40px 40px #cccccc,
                 0 0 0 #ffffff,
                 0 0 0 #cccccc inset,
                 2px 2px 2px #ffffff inset;
  }
}
<body>
  <div class="container">
    <div class="box"></div>
  </div>
</body>

Initially, the animation is paused. When the body is hovered but the box isn't, the animation is paused. When the box is hovered, the animation runs. I think it's what you needed.

1
  • Well yes and no. I want it to complete the animation on hover, but if i stop hovering, it will do the reverse of the animation back to the start smoothly.
    – Sparkylc2
    Commented Jan 25, 2021 at 13:37
0

I guess the the answer to your question would be something like this

function fn(el, isEnter) {
  el.className = "";
   requestAnimationFrame(() => {
    requestAnimationFrame(() => {
        el.className = isEnter? "in": "out";
    });
  });  
}
.in{
  animation: k 1s forwards;
}

.out{
  animation: k 1s forwards;
  animation-direction: reverse;
}

@keyframes k
{
from {transform: rotate(0deg);}
to   {transform: rotate(360deg);}
}
<div style="width:100px; height:100px; background-color:red" 
    onmouseenter="fn(this, true)"
    onmouseleave="fn(this, false)"  
    />

Not the answer you're looking for? Browse other questions tagged or ask your own question.