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;
}
}
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 an animation that has an infinite iterations count:
.spinner {
animation: spinnerAnimation 2s linear infinite;
}
What I want is to make the animation finish the current animation cycle and stop it on a button click (not really on a button click, but this is to make things easier to understand):
$("button").click(function() {
$(".spinner").addClass("stop");
})
This will add a stop class to the spinner:
.spinner.stop {
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
It doesn't work really smooth, but I don't care about smoothness much in this case:
http://codepen.io/Deka87/pen/OXZvdm
The only problem is that this won't stop the animation in IE edge, i.e. things don't work in IE (versions that support animations). Any ideas?
PS: animation-play-state: pause; is not what I need, because this won't make the animation finish the current animation cycle, but pause it in its current position instead.
PSS: I am really looking for a CSS only solution, i.e. make it work inside .spinner.stop{}.
You had a problem with the name of your keyframe name - spinnerAnimation vs preloaderAnimation
The only way I was able to set IE to stop the animation was to set animation: none; inside the .stop class:
$("button").click(function() {
$(".spinner").addClass("stop");
})
.spinner {
width: 30px; height: 30px;
background: green;
animation: spinnerAnimation 2s linear infinite;
}
.spinner.stop {
-webkit-animation-iteration-count: 1;
animation: none;
}
button {
margin-top: 20px;
}
#-webkit-keyframes spinnerAnimation {
0% {
-webkit-transform: rotate(0);
}
100% {
-webkit-transform: rotate(360deg);
}
}
#keyframes spinnerAnimation {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="spinner"></div>
<button>Stop spinner</button>
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 am trying to create a delay for an image to load. I have the following, but I really want it to delay loading for 10 seconds, not just fade in. How can I modify this to get a delay before loading?
.image {
animation: fadeinLoad 10s;
}
#keyframes fadeinLoad {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<img class="image" src="https://i.stack.imgur.com/od9bJ.png" />
We need to give the .image class opacity: 0 so it loads hidden. Then, delay the animation:
animation: fadeinLoad 1s 5s forwards;
The second time of 5s specifies a wait to activate time of 5 seconds. The forwards property pauses the animation at 100%.
The shorthand above is the same as this:
animation-name: fadeinLoad;
animation-duration: 1s;
animation-delay: 5s;
animation-fill-mode: forwards;
Read more on CSS animation over on the MDN.
Example
Count to five :)
.image {
animation: fadeinLoad 1s 5s forwards;
opacity: 0;
}
#keyframes fadeinLoad {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<h1>Count to 5!</h1>
<img class="image" src="https://i.stack.imgur.com/od9bJ.png" />
You can do this much simpler than keyframe animations.
Change your code to something like this:
#topHeader .image {
transition-delay: 10s;
transition: opacity 1s;
opacity: 0;
}
#topHeader .image.YOUR-FIRING-CLASSNAME-HERE {
opacity: 1;
}
Plus, the days of needing to prefix every CSS3 property are pretty much over. You don't need -o-, -ms-, etc. etc.
Save for keyframes, as those apparently don't have large-scale standardized support just yet.
I'm entering the world of CSS3 animations and transitions so please forgive my ignorance.
Here's the simplified version of what I'm trying to do:
I have a ball that "pulsates" infinitely via CSS3 keyframes
I want the ball to grow bigger and stay like that when I hover over it
I want the ball to become small again when I move the mouse away from it and keep pulsating (all the transitions need to be smooth, of course).
Here's my stab at it using a mix of CSS3 animations and transitions (testing this on Chrome so far, hence webkit prefixes):
#-webkit-keyframes pulsate {
from {
-webkit-transform: scale(0.7);
}
to {
-webkit-transform: scale(0.8);
}
}
.ball {
background: blue;
width: 100px;
height: 100px;
border-radius: 50%;
transition: all 1s;
-webkit-transform: scale(0.7);
-webkit-transform-origin: center center;
-webkit-animation-duration: 800ms;
-webkit-animation-name: pulsate;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: ease-in-out;
}
.ball:hover {
-webkit-transform: scale(2);
-webkit-animation-play-state: paused; /* transition works but gets reset at the end*/
/*-webkit-animation: 0;*/ /* transition works only one time, and no smooth transition on mouse out */
}
jsFiddle Demo
The result is pretty close but as soon as the ball finishes expanding on hover, it suddenly becomes small again (don't understand why). I also tried disabling the animation via -webkit-animation: 0; instead of pausing it but it doesn't work well either.
I tried a different approach that uses keyframes only (no transitions) by attempting to call a different keyframe set on hover:
#-webkit-keyframes pulsate {
from {
-webkit-transform: scale(0.7);
}
to {
-webkit-transform: scale(0.8);
}
}
#-webkit-keyframes expand {
to {
-webkit-transform: scale(2);
}
}
#-webkit-keyframes shrink {
to {
-webkit-transform: scale(0.7);
}
}
.ball {
background: blue;
width: 100px;
height: 100px;
border-radius: 50%;
transition: all 2s;
-webkit-transform: scale(0.7);
-webkit-transform-origin: center center;
-webkit-animation-duration: 800ms, 800ms;
-webkit-animation-name: shrink, pulsate;
-webkit-animation-iteration-count: 1, infinite;
-webkit-animation-direction: normal, alternate;
-webkit-animation-timing-function: ease-in-out, ease-in-out;
}
.ball:hover {
-webkit-animation-name: expand;
-webkit-animation-iteration-count: 1;
-webkit-animation-direction: normal;
-webkit-animation-fill-mode: forwards;
}
jsFiddle Demo
The ball stays big as long as the mouse is over it but there's still no smooth transition when the mouse moves away from the ball. I expect it to play the shrink animation instead but it doesn't.
Am I missing something or this is impossible to implement with just pure CSS at the moment?
// Related thread but didn't work for me: Stop animation and start transition on hover
You need to add an animation delay to allow the transition to complete because it reverts back to scale(.7) at the start of the animation. Updated jsFiddle
-webkit-animation-delay:1s;
EDIT
I realized that the answer I posted here was not fully correct. True, the delay animated the transition from big back to small, but if you hover over the pulsing ball when its expanded it jumps back to it's 0 value of .7 before animating to the large scale.
Updated Demo
I came up with a fix that just uses some javascript to fix it based on this article. You do have to change the CSS a little, but it's not very noticeable in the outcome. Here is the updated code
/* CSS */
body {margin: 100px;}
#-webkit-keyframes pulsate {
0% {
-webkit-transform: scale(0.7);
}
50% {
-webkit-transform: scale(0.8);
}
100% {
-webkit-transform: scale(0.7);
}
}
.ball {
background: blue;
width: 100px;
height: 100px;
border-radius: 50%;
-webkit-transform: scale(0.7);
-webkit-transform-origin: center center;
transition: all 1s;
}
.ball.animated {
-webkit-animation-duration: 1600ms;
-webkit-animation-name: pulsate;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: ease-in-out;
}
/* Javascript */
var ball = document.getElementsByClassName('ball')[0],
pfx = ["webkit", "moz", "MS", "o", ""],
hovered = false;
function AnimationListener() {
if(hovered)
{
ball.classList.remove('animated');
ball.style.webkitTransform = 'scale(2)';
ball.style.transform = 'scale(2)';
}
}
function TransitionListener() {
if(!hovered)
{
ball.classList.add('animated');
}
}
function PrefixedEvent(element, type, callback) {
for (var p = 0; p < pfx.length; p++) {
if (!pfx[p]) type = type.toLowerCase();
element.addEventListener(pfx[p]+type, callback, false);
}
}
PrefixedEvent(ball, "AnimationIteration", AnimationListener);
ball.onmouseover = function() {
hovered = true;
}
ball.onmouseout = function() {
hovered = false;
PrefixedEvent(ball, "TransitionEnd", TransitionListener);
ball.style.webkitTransform = 'scale(.7)';
ball.style.transform = 'scale(.7)';
}
Just update this CSS rule, I have added From & To - in Expand & Shrink:
#-webkit-keyframes expand {
from {
-webkit-transform: scale(1);
}
to {
-webkit-transform: scale(2);
}
}
#-webkit-keyframes shrink {
from {
-webkit-transform: scale(2);
}
to {
-webkit-transform: scale(1);
}
}