How to Run the CSS3 Animation to the End If the Selector Is Not Matching Anymore

How to run the CSS3 animation to the end if the selector is not matching anymore?

As discussed in comments there is currently no way to force an animation to complete one full cycle even after the selector rule which originally applied the animation is no longer applicable.

The only way to achieve this is by using scripting. Below is a sample snippet using JavaScript. What this does is to add a class (that has the animation property set) to the element when it gains focus and then remove it only when the animation ends.

Note:
I have used webkitAnimationEnd event in the snippet and so it would not work in other browsers. The code also needs more fine tuning because it currently removes the class only on animation end. So, if you tab out and tab in before one cycle is completed then nothing happens.

window.onload = function() {  var anchors = document.querySelectorAll('a');  for (var i = 0; i < anchors.length; i++) {    anchors[i].addEventListener('focus', function() {      addanim(this);    });    anchors[i].addEventListener('webkitAnimationEnd', function() {      endanim(this);    });  }
function addanim(el) { el.classList.add('focus'); }
function endanim(el) { el.classList.remove('focus'); }}
@keyframes pressed {  0%, 100% {    transform: scale(1);  }  50% {    transform: scale(2);  }}.focus {  animation: pressed 2s;}a,input {  border: 1px solid silver;  padding: 5px;  height: 40px;  line-height: 28px;  margin: 0px;  display: inline-block;  width: 33.3%;  box-sizing: border-box;  background: white;}a {  color: dodgerBlue;  text-decoration: none;}input {  color: red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<input type="text" id="foo" value="Start here, then press tab" /><a href="#">Lorem</a><a href="#">Ipsum</a><a href="#">dolor</a><a href="#">sit</a><a href="#">amet</a><a href="#">consectetur</a><a href="#">adipiscing</a><a href="#">elit</a>

Combination of animation and transition not working properly

This is sort of a known behavior with Chrome. Firefox does seem to be able to handle the removal of animation smoothly with transition but Chrome doesn't do so. I had seen this behavior happen earlier also in this thread.

Why does removal of an animation not work with transition in Chrome?

While I cannot provide a 100% fool-proof explanation of why this happens, we can decode it to some extent based on this HTML5Rocks article about Accelerated rendering in Chrome and this one about GPU accelerated compositing in Chrome.

What seems to happen is that the element gets its own rendering layer because it has explicit position property set on it. When a layer (or part of it) gets invalidated due to animation, Chrome only repaints that layer which is affected by the change. When you open the Chrome Developer Console, switch on "Show Paint Rects" option, you would see that when the animation is happening Chrome only paints the actual element that is getting animated.

However, at the start and end of animation a whole page repaint is happening which puts the element back into its original position immediately and thus overriding the transition behavior.

$('button').click(function(){  $('div').toggleClass('clicked');});
div{  background-color: #ccc;  height: 100px;  width: 100px;  transition-property: top, left;  transition-duration: 1s;  transition-timing-function: linear;  position: relative;  top: 0;  left: 0;}.clicked{  animation-name: clicked;  animation-duration: 1s;  animation-timing-function: linear;  animation-fill-mode: forwards;}@keyframes clicked{  0% {top: 0; left: 0;}  100% {top: 100px; left: 100px;}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><button type="button">Click Me!</button><div></div>

Why won't my CSS3 SVG Object animation go all the way across the screen?

to {transform: translateX(100%);} in the keyframe rules makes the svg container move by 100% of it's own width, not that of the parent element...

If you know the width of the svg element, you can use this type of rule (in my example the width would be 320px):

@keyframes pandaRight   {
from {left: 0px;}
to {left: calc(100% - 320px);}
}

https://jsfiddle.net/7t6gcfr0/

CSS animation restarts if I move the mouse when the container retracts. Can you avoid this?

The animation restarts when you hover inside the container and then move the mouse such that the mouse pointer is still inside the original boundaries of the element because the transform: rotateY() changes the element's boundaries once the animation has started and so even though you're moving the mouse within the original boundaries of the element it resets the animation (as the browser treats it as a mouse-out and a mouse-in).

This is very much noticeable when you hover close to the edges of the element. Hover the element close to the edge, let the animation start, do not move the mouse until the mouse is outside the border of the element when it is animating and move it again - this would cause the animation to reset/restart.

This can be overcome by adding the background-color and the transform on the a instead of the li when the li is being hovered on (like in the below snippet). Adding the animation to the a on li:hover works because the boundaries of the li no longer change during animation and so hover is always on.

.container {  height: 200px;  width: 100px;}.conteiner li {  display: inline-block;  float: left;  text-align: center;  height: 100%;  width: auto;}.conteiner li a {  position: relative;  display: flex;  align-items: center;  justify-content: center;  padding: 0 2em 0 2em;  border: solid 1px black;  background-color: white;}.conteiner li:HOVER a {  animation-name: menu_header_li;  animation-duration: 5s;  animation-timing-function: linear;}@keyframes menu_header_li {  0% {    transform: rotateY(0deg);    background-color: white;  }  50% {    transform: rotateY(90deg);    background-color: red;  }  100% {    transform: rotateY(0deg);    background-color: white;  }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script><ul class="conteiner">  <li>    <a>Element one </a>   </li>  <li>    <a>Element two </a>  </li></ul>

Continuous rotation on hover exit

Using CSS3 animation, we can make the block rotate from 0 to 180 degree on hover and then rotate from 180 to 360 degree when not hovered.

#block {  position: absolute;  width: 100px;  height: 50px;  left: 100px;  top: 100px;  background: black;  color: white;  animation-name: out;  /* animation to rotate on hover out*/  animation-duration: 1s;  /* duration for the animation, increase it to slow it down*/}#block:hover {  animation-name: in;  /* animation to rotate on hover */  animation-duration: 1s;}@keyframes in {  from {    transform: rotate(0deg);  }  to {    transform: rotate(180deg);  }}@keyframes out {  from {    transform: rotate(180deg);  }  to {    transform: rotate(360deg);  }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div id="block"></div>


Related Topics



Leave a reply



Submit