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.
Related
Current I am using some animations with my sliding ionic list such as sliding in from left to right and content from fading in as per this tutorial. https://www.joshmorony.com/how-to-create-animations-with-css-in-ionic/
#-webkit-keyframes animateInPrimary {
0% {
-webkit-transform: translate3d(-100%,0,0);
}
100% {
-webkit-transform: translate3d(0,0,0);
}
}
#-webkit-keyframes animateInSecondary{
0% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.animate-in-primary {
-webkit-animation: animateInPrimary;
animation: animateInPrimary;
-webkit-animation-duration: 750ms;
animation-duraton: 750ms;
}
.animate-in-secondary {
-webkit-animation: animateInSecondary ease-in 1;
animation: animateInSecondary ease-in 1;
-webkit-animation-duration: 750ms;
animation-duraton: 750ms;
}
Now I would want the ion-items to slide one after the other. I think I have to use the css property -webkit-animation-delay. But i am not sure where to insert it. Hope someone can help. Thanks,
Ashley
If you wanted to do this with CSS animations then what you would need to do is add an incremental class to each list item and then stagger your animations accordingly as demonstrated here: CSS Animations with delay for each child element
The easier way to do this is with the built in stagger function of the animations module - take a look at this article: https://coursetro.com/posts/code/78/Creating-Stagger-Animations-in-Angular-4#
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
I want to run an animation after a pause in a cycle. For EXAMPLE,
#-webkit-keyframes test {
0% { opacity:0; }
50% { opacity:1; }
100%{ opacity:0;}
}
.test {
-webkit-animation:test 5s linear 10s infinite forwards;
}
I want to pause/delay the animation for 10s, then doing the animation for 5s and repeating this cycles.
The above example, only works for the first cycle. How can I induce delay/pause in each cycle for infinite cycling? In other words, I need a 15s cycle but with 5s of animation of FULL keyframe (from 0% to 100%).
NOTE that I do not aim to change the keyframe percentages.
Without javascript what you desire is impossible without changing your current keyframes. You could do the following instead, but that is the only non-javascript fix for a delay each time
#-webkit-keyframes test {
0% { opacity: 0; }
16.66% { opacity: 1; }
33.33% { opacity: 0; }
100% { opacity: 0; }
}
.test {
-webkit-animation:test 15s linear infinite forwards;
}
Demo here
The only other way, like mentioned before, is to use javascript to reset the CSS animation. Helpful article on that here
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;
trying to flash three elements in a row with css3 animations. i've got it running, but there is a fade for each frame and i'd like to remove it. ideally each element stays visible for 1s, then hides immediately.
i've tried setting the animation with frames at 0% and 99% for opacity:1 and 100% for opacity: 0 but still no luck.
i hope theres a way to remove the fade!
webkit js fiddle
CSS:
.motion.play .frame {
-webkit-animation-name: flash;
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: linear;
}
.frame:nth-of-type(2) {
-webkit-animation-delay: 1s;
}
.frame:nth-of-type(3) {
-webkit-animation-delay: 2s;
}
#-webkit-keyframes flash {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
Just define your animation so that it keeps one state as long as possible and then switches to the other one as fast as possible. Like this:
#-webkit-keyframes flash {
0% { opacity: 1; }
49% { opacity: 1; }
50% { opacity: 0; }
100% { opacity: 0; }
}
Use proper animation-timing-function:
http://jsfiddle.net/rfGDD/1/ (WebKit only)
.motion.play .frame {
-webkit-animation-name: flash;
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: normal; /* not "linear" */
-webkit-animation-fill-mode:forwards;
-webkit-animation-timing-function:steps(3, end);
}
MDN document on fill-mode
MDN document on direction
MDN document on steps() timing function
Edit:
Oops, just realized the logical flaw.
Revised: http://jsfiddle.net/rfGDD/3/ (WebKit only)
In addition to the above change, change the flash animation to following:
#-webkit-keyframes flash {
0% {
opacity: 1;
}
33% {
opacity: 0;
}
100% {
opacity: 0;
}
}
The problem is, the animation plays 3 seconds, but each element need to stay in the opacity:0 state after second #1, so I need to split the animation into 2 stages (with the timing length ratio 1:2), so elements can look like they stays in final stage for 2 seconds.
You may keep the opacity for the longest period and change it very quickly.
Try this:
.blinkMe {
animation: blink 1s linear infinite;
}
#keyframes blink {
0%,50% {
opacity: 0;
}
51%,100% {
opacity: 1;
}
}