My animation uses keyframes, starts on hover and has a long duration.
When I move the mouse out while the animation is still running it stops instantly.
I need the interrupted animation returns to it's original values gradually. (Like 'transform' does).
#keyframes KF_Problem { 100% {transform:scale(2);} }
.Problem:hover { animation:KF_Problem 3s; }
.Problem { transform:scale(1); transition:3s;}
.All_OK:hover { transform:scale(2); transition:3s;}
.All_OK { transform:scale(1); transition:3s;}
1) How can I do that?
2) Why does Firefox "do the work" automatically and all other browsers don't?
Just try the code in http://www.w3schools.com/css/tryit.asp?filename=trycss_default with Firefox and with all other modern browsers to see the difference...
Related
Our team is developing in ServiceNow and have created a page with a widget that embeds several other widgets in different tabs. We're using the ng-show/ng-hide method to show/hide the specified tabs. We've added some very basic transition css to fade in and out the chosen tab:
.animate-switch {
transition: all linear 1s;
opacity: 1;
}
.animate-switch.ng-hide {
opacity: 0;
}
This works as expected-- the hiding tab fades out and clicked on tab fades in simultaneously, but when the fade out completes, there's a very noticeable jolt in the page to show the active tab.
Is there anything we can add to our css to make this transition a bit smoother?
I would suggest removing the "all" value in transition and just transition what you're actually using eg opacity. Watching everything that could possibly change is a bit expensive.
You might also want to force hardware acceleration (Your GPU is way better at this) by adding a 3d transform.
.animate-switch {
transition: opacity linear 1s;
transform: translateZ(0);
opacity: 1;
}
.animate-switch.ng-hide {
opacity: 0;
}
I've been investigating and odd behavior when viewing CSS animations on IE11. I've dug up multiple instances where IE11 struggles to digest CSS animations similar to Chrome/Firefox, but, I'd like to produce a solution to this "bug" once and for all.
Demonstration of behavior: http://recordit.co/6urL1s8XgR
As you can see, when the user interacts with the "button", the intended animation is to slide in from the bottom right, scale up and set the opacity to 1. A generic representation of the approach below:
.element {
...
opacity: 1;
animation: animate 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
#keyframes animate {
from {
opacity: 0;
transform: scale3d(0.5, 0.5, 0.5) translate3d(0, 0, 500px);
}
}
However, on IE11, it complete's the animation lower within the DOM than other browsers, causing the animated element to "jump up" from where it (incorrectly) ended (the animation), to where it needed to finish.
A similar demonstration can be observed at the following url: https://chemonics.com/region/
I've resolved this issue with isolating the problem being the animation-fill-mode property of "forwards" was not present. This was causing the animation to (which only had a 0% keyframe defined for the animation) to end (at 100%) by inheriting the styles of the elements initial state (prior to the animation). With more modern browsers, they "fill in the gaps" whereas with IE11, well, it jumps between the gaps.
https://drafts.csswg.org/css-animations-1/#valdef-animation-fill-mode-forwards
On a Mac, if you hold the Shift key and perform an action that involves animation, it will slow down the animation. For example, hold Shift and minimise a window. This effect is described in various places (e.g. YouTube, Apple - StackExchange, The Unofficial Apple Weblog).
It would be nice to slow down CSS animations/transitions in a similar way. Is there a way to achieve this (apart from simply tweaking the animation-duration value in the CSS)?
You could combine some javascript and CSS to accomplish the effect on a consistent basis, meaning you won't have to go into your code anymore. Heres the code I tried:
function keydown(event){
if(event.which == 16) document.body.className = "slowmotion";
}
function keyup(event){
document.body.className = "";
}
if (window.addEventListener) {
window.addEventListener('keydown', keydown, false);
window.addEventListener('keyup', keyup, false);
} else if (window.attachEvent) {
window.attachEvent('keydown', keydown);
window.attachEvent('keyup', keyup);
}
And heres the CSS:
#keyframes move {
0% {left: 0}
50% {left: 100%}
100% {left: 0}
}
#-webkit-keyframes move {
0% {left: 0}
50% {left: 100%}
100% {left: 0}
}
body > div {
position: absolute;
background: red;
width: 50px;
height: 50px;
background: red;
-webkit-animation: move 4000ms infinite;
animation: move 4000ms infinite;
}
body.slowmotion * {
-webkit-animation-duration: 8000ms !important;
animation-duration: 8000ms !important;
}
And the HTML:
<div>MOVING</div>
What we're doing here is adding a class to the body to indicate we want our duration value overwritten. It will not do it immediately (in Safari it restart the animation) [EDIT: The animation does not get restarted, but gets recalculated (i.e. it reverts to where it would have been in if the other animation had been ongoing)], but it does allow for modification that way. You can even do it for elements with different speeds by doing .slowmotion #myElementID and amending the duration there. Make sure to always include the important, as the class is only triggered when the key is pressed and HAS to overwrite anyway.
Chrome and Firefox developer tools now support slowing down of many kinds of animations.
Chrome:
In the 'Styles' tab of DevTools, look for an 'Animations' icon that opens up the Animations Inspector. More info:
Chrome DevTools Animation Inspector
New animation controls in Chrome Canary
Firefox:
See documentation on working with animations
I'm using SASS so my CSS syntax looks weird, but anyway, the problem is, that my rotate animation starts well on chrome and firefox, but works only partially on Safari. To be specific, rotateY, scale, skew work normally, but rotate and translateX don't. What is more importat, after I go to another tab and then go back in Safari - suddenly it works as expected.
This is the animation in Safari (before switching tabs):
Safari
Instead of that:
Chrome
Basically, all images appear in the center, and only scale and rotateY animation works, but translate and rotate transitions don't.
To keep it simple this is only the part of the code I use for Safari:
#mixin orbit ($name,$time,$modifier,$skewX,$skewY,$perspective,$rotateY,$startScale,$middleScale){
#at-root (without: media) {
#-webkit-keyframes myOrbit_#{$name} {
from { -webkit-transform: rotate($modifier+deg) translateX(150%) rotate($modifier+deg) skewX($skewX+deg) skewY($skewY+deg) perspective($perspective+px) rotateY(0deg) scale($startScale,$startScale); }
50% { -webkit-transform: rotate($modifier+(-180)+deg) translateX(150%) rotate($modifier+180+deg) skewX($skewX+deg) skewY($skewY+deg) perspective($perspective+px) rotateY($rotateY/2+deg) scale($middleScale,$middleScale); }
to { -webkit-transform: rotate($modifier+(-360)+deg) translateX(150%) rotate($modifier+360+deg) skewX($skewX+deg) skewY($skewY+deg) perspective($perspective+px) rotateY($rotateY+deg) scale($startScale,$startScale); }
}
-webkit-animation: myOrbit_#{$name} $time+s linear infinite;
}
I've noticed that when I defined the animation with
-webkit-animation-play-state: paused;
then the "satellites" were positioned properly. So the solution was to start the animation with time offset. In my case this helped:
-webkit-animation-delay: 5ms;
One tricky thing was that I had to put it after other -moz- -o- and "regular" animation properties, otherwise is didn't work, like if it was overwritten.
When doing CSS3 animation, is it possible to stay at the end of the animation for a few seconds and then go back to the original state?
I know you can make the CSS3 animation end on the last frame, or go back to the first frame, but I want to to pause at the last frame for a few seconds then go back to the beginning.
Thank you.
Sure. You'll have to do some math, though, because keyframe stops are measured in percentage of total animation. Let's say your total animation should last 12 seconds -- that means your animation should be unmoving for the last 25% of the total animation time. I'll modify an example from W3schools to demonstrate this.
div.animated {
-webkit-animation: with_delay 12s linear 0s infinite; /* Chrome, Safari, Opera */
animation: with_delay 12s linear 0s infinite; /* Standard syntax */
}
/* Chrome, Safari, Opera */
#-webkit-keyframes with_delay {
0% {background: red;}
75% {background: green;}
100% {background: green;}
}
/* Standard syntax */
#keyframes with_delay {
0% {background: red;}
75% {background: green;}
100% {background: green;}
}
Here is a live demo.
Note that if you don't mind the delay being at the beginning of the animation instead of the end, it's even easier. Simply specify animation-delay or transition-delay depending on which animation technique you already have implemented.
I believe you'll need a little Javascript to make it work. You can detect the end of the animation via Javascript, run a timer, and when the timer completes you can reset and restart the animation.
Here's some references:
CSS Animation Callback
Restart CSS Animation