How to animate an SVG on view once and then on every hover?

Viewed 414

I have this animation on a div. What I want is when the page loads, it should animate once. And when I hover over it, it should animate once again.

The animation works fine when it's just on hover or just on load. But when I try to have it both ways (like in my example) it does not work. Why doesn't it work?

I also tried instead of defining the animation again on hover just putting in animation-play-state: running but that did not work either. When I look at it in chrome dev tools and force hover on the box element, I can see that the selectors are there, but the animation does nothing.

What's also curious is when I set the animation in hover to infinite with animation: test 1s infinite; then it works. It just not works when I want it to run once.

@keyframes test {
  0% {
    transform: scale(1);
  }
  25% {
    transform: scale(1.25);
  }
  80% {
    transform: scale(0.85);
  }
  100% {
    transform: scale(1);
  }
}

.box {
  width: 300px;
  height: 300px;
  background-color: black;
  display: block;
  animation: test 1s;
}

.box:hover {
  animation: test 1s;
}
<div class="box"></div>

3 Answers

There is a solution, I have little edited your CSS code, I divided "animation" code with "animation-name: test" and "animation-duration: 1s" but you can use it also in only "animation" parameter too, this is not a problem, problem is that you have used one animation name for hover and normal position of block, you should use 2 names and 2 keyframes

here is code:

  .box {
    width: 300px;
    height: 300px;
    background-color: black;
    display: block;
    animation-name: test-primary;
    animation-duration: 1s;
  }
  
  .box:hover {
    animation-name: test-secondary;
    animation-duration: 1s;
  }
@keyframes test-primary {
    0% { transform: scale(1); }
    25% { transform: scale(1.25); }
    80% { transform: scale(0.85); }
    100% {transform: scale(1);
    }
  }
  
  @keyframes test-secondary {
    0% { transform: scale(1); }
    25% { transform: scale(1.25); }
    80% { transform: scale(0.85); }
    100% {transform: scale(1);
    }
  }

This works, just try this variant I hope I helped you :)

While perhaps unsatisfying, you can get the result by duplicating the animation:

@keyframes test {
  0% {
    transform: scale(1);
  }
  25% {
    transform: scale(1.25);
  }
  80% {
    transform: scale(0.85);
  }
  100% {
    transform: scale(1);
  }
}

@keyframes copytest {
  0% {
    transform: scale(1);
  }
  25% {
    transform: scale(1.25);
  }
  80% {
    transform: scale(0.85);
  }
  100% {
    transform: scale(1);
  }
}

.box {
  width: 300px;
  height: 300px;
  background-color: black;
  display: block;
  animation: test 1s;
}

.box:hover {
  animation: copytest 1s;
}
<div class="box"></div>

You can rely on transition later to simulate the same effect of your animation. I am relying on cubic-bezier() to create such effect and I invite you to read the my article around it to understand how it works: https://css-tricks.com/advanced-css-animation-using-cubic-bezier/

@keyframes test {
  25% {
    transform: scale(1.25);
  }
  80% {
    transform: scale(0.85);
  }
}

.box {
  width: 300px;
  height: 300px;
  background-color: black;
  display: block;
  animation: test 1s;
}

.box:hover {
  transform:scale(1.02);
  transition:1s cubic-bezier(0.5,50,0.5,-50);
}
<div class="box"></div>

Related