Gyuzal R Gyuzal R - 6 months ago 19
HTML Question

Using two animations on one element, CSS

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
.

Answer

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 animation-iteration-count is 1 and that this animation is actually never removed from the element even when the :hover is on.

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 and also to make it clear that it shouldn't be changed if this approach has to work fine.)

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>