2

I have two animations: on element load and hover:

div {
     animation: slide-up 2s;
    -webkit-animation: slide-up 2s;
    -moz-animation: slide-up 2s;
}
div:hover{
    animation: rotate 2s;
   -webkit-animation: rotate 2s;
   -moz-animation: rotate 2s;
}

The slide-up animation runs once the element is loaded, and rotate runs when element is hovered. However, now the element slides up on mouse leave and I don't know how to prevent this. So I'd like to turn off slide-up animation on hover.

The rotate animation uses transform property, and slide-up just changes margins.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Gyuzal
  • 1,581
  • 10
  • 52
  • 99
  • only `rotate` uses `transform` property, and `slide-up` just changes margins. Is it possible then? – Gyuzal May 25 '16 at 05:12
  • Thank you, then is it possible to use `rotate` animation both on load and hover? – Gyuzal May 25 '16 at 05:18
  • tl;dr of the [answer](https://stackoverflow.com/a/37428424/114558) by @Harry (go upvote it) - Make sure that the animation is never removed from the element. – rinogo Sep 01 '21 at 16:05

3 Answers3

7

Reason:

The slide-up animation executes once again when you move the mouse out of the element because of the following reasons:

  • On load, the element has only one animation (which is slide-up). The browser executes this.
  • On hover, the animation property again specifies only one animation (which is rotate). This makes the browser remove the slide-up animation from the element. Removing the animation makes the browser also forget about the execution state or the execution count of it.
  • On hover out, the default div selector becomes applicable for the element and so the browser again removes the rotate animation and attaches the slide-up animation. Since it is being re-attached, the browser thinks it must execute it again.

Solution:

You can make the slide-up animation run only once by making sure that the animation is actually never removed from the element even when :hover is on and animation-iteration-count is 1.

In the below snippet, you'd note how I have retained the slide-up animation definition within :hover selector also. This makes the browser see this animation as ever present and since this animation is already executed once on load, it won't execute it again (because of iteration count).

(Note: Just to avoid any confusions - the default value for animation-iteration-count is 1 but I had made it explicit for the purpose of explanation. It is not the primary reason but is just an extra step to make sure that its value doesn't mess up the solution.)

div {
  height: 100px;
  width: 100px;
  border: 1px solid;
  animation: slide-up 2s 1;
}
div:hover {
  animation: slide-up 2s 1, rotate 2s forwards;
}
@keyframes slide-up {
  from {
    margin-top: 100px;
  }
  to {
    margin-top: 0px;
  }
}
@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(60deg);
  }
<div>Some div</div>
Harry
  • 87,580
  • 25
  • 202
  • 214
  • I don't think its the iteration count. Whats making it work is the added animation and the animation-fill-mode. On hover you are adding another animation this way `animation-name: slide-up, rotate;` and `animation-fill-mode:forwards` is adding the property values to the div and preserving it. Don't you think? – AA2992 May 25 '16 at 06:00
  • 1
    It is primarily the *retention* of the animation on the hover selector but the iteration count also plays its part (it will cause problems if you change it to some other value, say infinite). The `animation-fill-mode: fowards` is applied only to the `rotate` animation and it has no effect on this. – Harry May 25 '16 at 06:02
  • 1
    Hmm makes sense. Just confusing cos that's a shorthand way of writing it. Upvoted already! Thanks! – AA2992 May 25 '16 at 06:07
  • @AnkithAmtange: I have edited my answer also a bit to make it clear. I guess the wording didn't convey this properly enough. So, thanks for the comment :) – Harry May 25 '16 at 06:16
  • @Harry, I'm sorry could you please take a look at my question http://stackoverflow.com/questions/37413746/smooth-css-animation-with-sprite, I would be so grateful. – Gyuzal May 25 '16 at 09:02
1

just add an animation-play-state: paused;

div:hover{
    animation: rotate 2s, slide-up paused;
   -webkit-animation: rotate 2s, slide-up paused;
   -moz-animation: rotate 2s, slide-up paused;
}
warkentien2
  • 969
  • 13
  • 20
  • Won't this pause *all animations* on the element, though? This would be a fantastic solution if it could be used to pause the animation associated with a specific `animation` property, but that doesn't seem to be the case. – rinogo Sep 01 '21 at 16:01
0

Just add another animation after a comma. For example, if I want to create a box that will fade in(1st animation) and then its shadow size keeps on changing(2nd animation), then this is the CSS that I am gonna use:

#box{
    width: 300px;
    height: 250px;
    border: 2px solid white;
    border-radius: 20px;
    display: block;
    margin-left: 500px;
    margin-top: 190px;
    background-color: rgb(0, 204, 228);
    animation: animate1 3s 1, animate2 1s infinite;
    text-align: center;
}

@keyframes animate1{
    0% {
        opacity: 0;
    }
    100%{
        opacity: 1;
    }
}

@keyframes animate2{
       0%{box-shadow: 0px 0px 10px 0px gray; }
       50%{box-shadow: 0px 0px 30px 0px gray; }
       100%{box-shadow: 0px 0px 10px 0px gray; }
}
General Grievance
  • 4,555
  • 31
  • 31
  • 45
aditya
  • 1