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
Related
This question already has answers here:
Different timing functions for different parts of css3 keyframe animation? (accurate bounce)
(1 answer)
How to have multiple CSS transitions on an element?
(9 answers)
Is there a way for animation-timing-function to apply to the entire animation instead of each keyframe?
(4 answers)
Closed 1 year ago.
I'm trying to create an animation with many steps.
I want a different value of transition for each change of style state.
However, using transition inside #keyframes has no effect.
.square {
background-color: #333;
height: 100px;
width: 100px;
animation: 4s move infinite;
}
#keyframes move {
0% {
transition: ease-in;
}
50% {
transform: translate(100%);
transition: ease-out;
} 100% {
transform: translate(0);
transition: cubic-bezier(0.25, 0.1, 0.6, 1.8);
}
}
<div class="square"></div>
I wonder if there is a way to have different transitions for each stage of an animation without having to combine multiple animation in wrapped elements.
The transition property doesn't do anything inside of keyframes. You can either use the transition property to specify how the paint transitions between selectors/transforms (ie, default and :hover), or you can use keyframes to specify how it transforms over time range (ie, from/to, or 0%, 50%, 100% etc).
When you think about it, they're two separate ways of expressing the same information.
You can use the animation-timing-function property in the individual keyframes if you want more control over transitions. Just know it wasn't supported in Safari (iOS/OSX) until around 2015, so you might run into trouble if you need to support those versions.
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 want to hide an HTML element when the page loads, then fade it in with a CSS transition. My plan is to set the opacity to 0, and then use a CSS animation to transform it to 1.
But I am worried that the content will remain hidden in old browsers that can't handle CSS transitions.
Is there a safer way to hide the content? Or to exclude this code from browsers that can't handle it?
As always, your problem is with older versions of IE.
http://caniuse.com/#feat=css-animation
I'm a big believer in progressive enhancement amd handling things CSS only.
Using Javascript could provide fallback for older browser or using libraries like Modernizr but I hate these kind of solutions and they come with there own problems. What if the visitor has JS disabled?
Luckily we can safely let older browser ignore the fade in animation. Just set opacity on 1 for the default div you want to fade in and start the keyframe animation at opacity set to 0.
div {
height: 300px;
width: 300px;
background-color: red;
opacity: 1;
animation: fadeIn 7s ease infinite;
}
#keyframes fadeIn {
0% { opacity: 0; }
50% { opacity: 1; }
100% { opacity: 0; }
}
https://jsfiddle.net/3rzL0xz8/
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...
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.