Situation
The DOM element initial state is opacity: 0.
I'm adding animation class to a DOM element. Aside of the animation, this class has an initial state of opacity: 1.
.animation {
opacity: 1;
animation(fadeIn 1s 200ms ease-in-out);
}
The animation is executed with a delay of 200ms, and has an initial state of opacity: 0.
#keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Problem
When the animation class gets apended to the DOM element, the element becomes instantly visible for 200ms, after which, the fadeIn animation begins by flickering the DOM element back to invisible state. Contrary to this, I would like for the animation (keyframes) attribute opacity:0 to overwrite the animation class attribute opacity:1 and as a result have a smooth fadeIn animation.
Reason for this approach is older-browser support.
EDIT: Added the actual project code ( for clarification purposes )
#for $i from 1 through 3 {
&.showAddonColumn#{$i} {
td:nth-child( #{$i + 1} ) {
display: table-cell;
}
#for $j from 1 through 15 {
tr:nth-child( #{$j} ) {
td {
.checkable {
#include transform-origin(50%, 0%);
#include animation(leafShow 1s #{$j*100ms} cubic-bezier(.37,0,.16,.94) 1);
#include animation-fill-mode(forwards);
}
}
}
}
}
}
You could manually delay the animation itself:
#keyframes fadeIn {
0% { opacity: 0; }
17% { opacity: 0; }
100% { opacity: 1; }
}
and extend the animation:
animation: fadeIn 1200ms ease-in-out;
Related
Display None to Display Block animation is working
but I need the animation to work this way also
- Animation Display Block to Display None
the animations is not working when action go from block to Display None
have an idea what can be the problem?
#dboldDiv,#dbnewDiv {
animation: anim .4s ease-in-out;
}
#keyframes anim {
0% {
display: none;
opacity: 0;
}
1% {
display: block;
opacity: 0;
transform: scale(0.8);
}
100% {
opacity: 1;
transform: scale(1);
}
}
display is not animatable property
There are two category of properties animatable and not animatable
you can check animated properties list from here :
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
display:none won't work smooth.
For fluent disappearing try using visibility:hidden, or if just keep 0 opacity and add pointer-events:none, so the object doesn't catch any mouse events.
document.getElementById('hide').addEventListener('click', function(){
document.getElementById('link').className = 'hide';
});
document.getElementById('show').addEventListener('click', function(){
document.getElementById('link').className = 'show';
});
document.getElementById('link').addEventListener('click', function(){
alert('clicked');
});
#link {
display:block;
}
#link.show {
animation: anim1 .4s;
animation-fill-mode: forwards;
}
#link.hide {
animation: anim2 .4s;
animation-fill-mode: forwards;
animation-direction: reverse;
}
#keyframes anim1 {
0% {
opacity: 0.3;
pointer-events:none;
}
100% {
opacity: 1;
pointer-events:all;
}
}
#keyframes anim2 {
0% {
opacity: 0.3;
pointer-events:none;
}
100% {
opacity: 1;
pointer-events:all;
}
}
<button id="hide">Hide</button>
<button id="show">Show</button>
hidding & showing
I am adding classes dynamically to a table based on when that data is loaded or loading.
I have:
#keyframes row-loading {
0% {
opacity: 1.0;
}
100% {
opacity: 0.3;
}
}
#keyframes row-loaded {
0% {
opacity: 0.3;
}
100% {
opacity: 1.0;
}
}
Used by:
tr {
height: 45px;
&.loading {
-webkit-animation: row-loading 0.8s;
-webkit-animation-fill-mode: forwards;
}
&.loaded {
-webkit-animation: row-loaded 0.8s;
}
...
The problem is, if the data loads too quickly, the .loaded class is applied and opacity jumps to 0, rather than starting from when .loading left it.
How can I get this to start fading in from where the previous class left off?
you can try transition instead of animation like so
tr {
height: 45px;
opacity:1;
transition: opacity 0.8s;
&.loading {
opacity: 0.3;
}
}
when you start loading data add "loading" class to "tr" so a transition will begin to opacity:1 to opacity:0.3; and when data finishes loading just remove "loading" class it will return back to its original opacity
Consider the following example: http://jsfiddle.net/HB7LU/23956/
Buttons add and remove work properly and so do their animations. Here is my question: How can I animate elements when button Remove is clicked, so that all elements under the element to be removed will slowly float up and not just jump to their new place?
When remove of B is clicked, I would like to animate C and D to the previous position of B and C, respectfully.
A remove
B remove
C remove
D remove
Solutions using maxheight are not preferable because of the responsive design. Thanks.
this can be a solution:
#keyframes animateIn {
0% { opacity: 0; transform: translate(0,-25px);}
100% { transform: translate(0,0px); }
}
#keyframes animateUp {
0% { transform: translate(0,0px); }
100% { transform: translate(0,-25px);}
}
#keyframes animateOut {
0% { opacity: 1; }
100% { opacity: 0; }
}
div.animate-repeat.ng-enter,
div.animate-repeat.ng-enter-active {
animation: animateIn 0.5s;
}
div.animate-repeat.ng-leave,
div.animate-repeat.ng-leave-active ~ div.animate-repeat{
animation: animateUp 0.5s;
}
div.animate-repeat.ng-leave-active{
animation: animateOut,animateUp 0.5s;
}
fiddle
In my web application, I'd like to display a message to the user after signing in or out that fades after a few seconds. I'd like to accomplish this animation with CSS.
Here is my stylesheet:
#keyframes fadeout {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.flash-message {
animation: fadeout 1s 3s;
}
This almost works: after a three-second delay, it begins to fade, then it takes one second to complete the animation. The problem is after the animation is complete the message reappears.
This is what I have to do to get the message to stay hidden:
#keyframes fadeout {
0% {
opacity: 1;
}
75% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.flash-message {
animation: fadeout 4s;
opacity: 0;
}
It seems like there should be an easier way to get the first version to work. Am I missing something or do I have to have opacity: 0 on the class as in the second version?
Use animation-fill-mode and set it to forwards:
#keyframes fadeout {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.flash-message {
animation: fadeout 1s 3s forwards;
}
As Jason's answer explains, animation-fill-mode is the way to go. It defines if and how CSS properties are applied outside of the animation.
Its default setting is none, which applies the properties only while the animation is executing.
Setting it to forwards permanently applies the properties from the last keyframe value.
See the list of values for more info.
I have a div which I need to animate it's opacity from 1 - 0, and THEN hide it, as some of you may know, adding display properties just override transitional values and hide the element straight away, so I'm wondering if there's a way with css to animate it's opacity, and THEN hide it?
Here's what I've tried:
#keyframes infrontAnimation {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 1;
}
50% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
}
100% {
display: none;
}
}
This doesn't work, it just hides straight away, it also doesn't stay at the 100% value:
Using it like this:
animation: infrontAnimation 1s 2s ease-out;
So my question is, is it possible to hide something, but only after a certain animation is finished?
Rather than setting the height or width of an element, I found a different approach, that to me, isn't as dodgy as forcing the height at 99.9%. Here's what I came up with:
First, Rather than using display to hide & show it, I used visibility, seeing as it's still something that can interrupt our animation and ultimately cause it to fail, I setup our transition properties initially:
Note: I'll keep other prefixes out for this demo:
.item {
transition: visibility 0s linear 0.7s, opacity 0.7s ease-in-out;
}
So what we're doing is setting the transition of the visibility attribute to 0, but delaying it by the time it takes to complete the fade out (opacity);
So when we want it to be visible, we add the class of visilble:
.item.visible {
transition-delay: 0s;
visibility: visible;
opacity: 1;
}
So we're setting our delay to 0 here so that we can override the state when it transitions in, obviously we dont' want to delay the visibility, we want to set that straight away and then animate our opacity;
Then when we want to hide it:
.item.hidden {
opacity: 0;
visibility:hidden;
}
Then all this is doing is transitioning our opacity back to 0, and leaving our delay at 0.7 so that it doesn't actually 'dissappear' in the dom until the opacity has finished.
Detailed Working Example
Fist of all, I've created a Fiddle to show what can be done. The red bars represent other content, like text.
Say, if you want to hide it in a way that it first fades, then shrinks, you could use
#-webkit-keyframes infrontAnimation {
0% {
opacity: 1;
}
50% {
opacity: 0;
height: 200px;
}
100% {
opacity: 0;
height: 0;
}
}
#keyframes infrontAnimation {
0% {
opacity: 1;
}
50% {
opacity: 0;
height: 200px;
}
100% {
opacity: 0;
height: 0;
}
}
animation: infrontAnimation 1s 2s forwards ease-out;
-webkit-animation: infrontAnimation 1s 2s forwards ease-out;
Note that both #keyframes as #-webkit-keyframesare used.
If you need to hide it without shrinking animation, you might want to use this
#-webkit-keyframes infrontAnimation {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
99.9% {
opacity: 0;
height: 200px;
}
100% {
opacity: 0;
height: 0;
}
}
#keyframes infrontAnimation {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
99.9% {
opacity: 0;
height: 200px;
}
100% {
opacity: 0;
height: 0;
}
}
You need to set animation-fill-mode: with the value forwards so it ends on the last frame of the animation.
See: http://dev.w3.org/csswg/css-animations/#animation-fill-mode