How can I convert this CSS3 animation into a Sass mixin? - css

I have the following animation code...
.a {
background: url(../Images/experience-1.jpg) center center no-repeat red;
z-index: 7;
-webkit-animation-delay: 3s;
-webkit-animation-duration: 5s;
-webkit-animation-name: fadeout;
-webkit-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-moz-animation-delay: 3s;
-moz-animation-duration: 5s;
-moz-animation-name: fadeout;
-moz-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-o-animation-delay: 3s;
-o-animation-duration: 5s;
-o-animation-name: fadeout;
-o-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
animation-delay: 3s;
animation-duration: 5s;
animation-name: fadeout;
animation-fill-mode: forwards; /* this prevents the animation from restarting! */
}
.b {
background: url(../Images/experience-2.jpg) center center no-repeat yellow;
z-index: 6;
-webkit-animation-delay: 18s;
-webkit-animation-duration: 5s;
-webkit-animation-name: fadeout;
-webkit-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-moz-animation-delay: 18s;
-moz-animation-duration: 5s;
-moz-animation-name: fadeout;
-moz-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-o-animation-delay: 18s;
-o-animation-duration: 5s;
-o-animation-name: fadeout;
-o-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
animation-delay: 18s;
animation-duration: 5s;
animation-name: fadeout;
animation-fill-mode: forwards; /* this prevents the animation from restarting! */
}
.c {
background: url(../Images/experience-3.jpg) center center no-repeat pink;
z-index: 5;
-webkit-animation-delay: 33s;
-webkit-animation-duration: 5s;
-webkit-animation-name: fadeout;
-webkit-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-moz-animation-delay: 33s;
-moz-animation-duration: 5s;
-moz-animation-name: fadeout;
-moz-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-o-animation-delay: 33s;
-o-animation-duration: 5s;
-o-animation-name: fadeout;
-o-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
animation-delay: 33s;
animation-duration: 5s;
animation-name: fadeout;
animation-fill-mode: forwards; /* this prevents the animation from restarting! */
}
.d {
background: url(../Images/experience-4.jpg) center center no-repeat green;
z-index: 4;
-webkit-animation-delay: 48s;
-webkit-animation-duration: 5s;
-webkit-animation-name: fadeout;
-webkit-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-moz-animation-delay: 48s;
-moz-animation-duration: 5s;
-moz-animation-name: fadeout;
-moz-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-o-animation-delay: 48s;
-o-animation-duration: 5s;
-o-animation-name: fadeout;
-o-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
animation-delay: 48s;
animation-duration: 5s;
animation-name: fadeout;
animation-fill-mode: forwards; /* this prevents the animation from restarting! */
}
.e {
background: url(../Images/experience-5.jpg) center center no-repeat orange;
z-index: 3;
-webkit-animation-delay: 63s;
-webkit-animation-duration: 5s;
-webkit-animation-name: fadeout;
-webkit-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-moz-animation-delay: 63s;
-moz-animation-duration: 5s;
-moz-animation-name: fadeout;
-moz-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-o-animation-delay: 63s;
-o-animation-duration: 5s;
-o-animation-name: fadeout;
-o-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
animation-delay: 63s;
animation-duration: 5s;
animation-name: fadeout;
animation-fill-mode: forwards; /* this prevents the animation from restarting! */
}
.f {
background: url(../Images/experience-6.jpg) center center no-repeat purple;
z-index: 2;
-webkit-animation-delay: 78s;
-webkit-animation-duration: 5s;
-webkit-animation-name: fadeout;
-webkit-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-moz-animation-delay: 78s;
-moz-animation-duration: 5s;
-moz-animation-name: fadeout;
-moz-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-o-animation-delay: 78s;
-o-animation-duration: 5s;
-o-animation-name: fadeout;
-o-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
animation-delay: 78s;
animation-duration: 5s;
animation-name: fadeout;
animation-fill-mode: forwards; /* this prevents the animation from restarting! */
}
...and what I want to do is to make it easier in future to change the values.
Just to explain that each class is applied to a div with a background image and each div is absolutely positioned on top of each other. So fading out the top div will show the other div below it.
The initial animation delay is 3 seconds and then the duration for each div is always 5 seconds.
But for each class I'm delaying the animation by the same amount of time it takes the previous animation to finish.
So the .b{} class is set to delay by 18 seconds. The way this is worked out is: the first animation has a 3 second delay + 5 second duration, which equals 8 seconds in total + 10 seconds extra for the user to properly see the next image.
So the c.{} class is set to delay by 33 seconds. And again the algorithm is: the second animation has a 18 second delay + 5 second duration, which equals 23 seconds in total + 10 seconds extra for the user to properly see the next image.
So this is the premise of the animation and I need to work out how to automate this via Sass (in case the client says "you know what, I want the duration to be 10 seconds now").
Thanks in advance for any help you can give me.

Step 1. Wrap it in a mixin, track duration with variables
For starters, you can wrap the whole block in a mixin and use some variables (global, so be careful) to track total duration and animation index:
$queue-max-z-index: 7;
$queue-total-delay: 0;
$queue-index: 0;
#mixin queue-animation($class, $color, $delay: 0, $duration: 5s, $viewing-time: 10s) {
.#{$class} {
background: url(../Images/experience-#{$queue-index + 1}.jpg) center center no-repeat $color;
z-index: $queue-max-z-index - $queue-index;
-webkit-animation-delay: $queue-total-delay + $delay;
-webkit-animation-duration: $duration;
-webkit-animation-name: fadeout;
-webkit-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-moz-animation-delay: $queue-total-delay + $delay;
-moz-animation-duration: $duration;
-moz-animation-name: fadeout;
-moz-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
-o-animation-delay: $queue-total-delay + $delay;
-o-animation-duration: $duration;
-o-animation-name: fadeout;
-o-animation-fill-mode: forwards; /* this prevents the animation from restarting! */
animation-delay: $queue-total-delay + $delay;
animation-duration: $duration;
animation-name: fadeout;
animation-fill-mode: forwards; /* this prevents the animation from restarting! */
$queue-total-delay: $queue-total-delay + $delay + $duration + $viewing-time;
$queue-index: $queue-index + 1;
}
}
Now you can set up your animations like this:
#include queue-animation(a, red, 3s);
#include queue-animation(b, yellow);
#include queue-animation(c, pink);
#include queue-animation(d, green);
#include queue-animation(e, orange);
#include queue-animation(f, purple);
The function default values represent global defaults that you can override for an individual animation. Also note that it automatically tracks the count (index) of animations set up and the total duration of said animations, so you can alter the duration or delay on any one and all the subsequent animations will be updated.
Step 2. Clean up those prefixes
To refactor a little more, you could include a little helper I use for vendor prefixed properties:
// Apply common prefixes to a property.
#mixin prefix($property, $value, $apply-to: property, $prefixes: -webkit -khtml -moz -ms -o) {
#if $apply-to == property {
#each $prefix in $prefixes {
#{$prefix}-#{$property}: $value;
}
} #else if $apply-to == value {
#each $prefix in $prefixes {
#{$property}: $prefix + -$value;
}
} #else if $apply-to == both {
#each $prefix in $prefixes {
#{$prefix}-#{$property}: $prefix + -$value;
}
}
#{$property}: $value;
}
And now your function looks like this:
#mixin queue-animation($class, $color, $delay: 0s, $duration: 5s, $viewing-time: 10s) {
.#{$class} {
background: url(../Images/experience-#{$queue-index + 1}.jpg) center center no-repeat $color;
z-index: $queue-max-z-index - $queue-index;
#include prefix(animation-delay, $queue-total-delay + $delay);
#include prefix(animation-duration, $duration);
#include prefix(animation-name, fadeout);
#include prefix(animation-fill-mode, forwards); /* this prevents the animation from restarting! */
$queue-total-delay: $queue-total-delay + $delay + $duration + $viewing-time;
$queue-index: $queue-index + 1;
}
}
Step 3. Use the animation shorthand
Going a step further, you can use the animation shorthand:
#mixin queue-animation($class, $color, $delay: 0s, $duration: 5s, $viewing-time: 10s) {
.#{$class} {
background: url(../Images/experience-#{$queue-index + 1}.jpg) center center no-repeat $color;
z-index: $queue-max-z-index - $queue-index;
#include prefix(animation, fadeout $duration ($queue-total-delay + $delay) forwards);
$queue-total-delay: $queue-total-delay + $delay + $duration + $viewing-time;
$queue-index: $queue-index + 1;
}
}
Humble disclaimer
I am still relatively new to Sass, so my advice is subjective and may not be in line with best practices. It's up to you how far you're happy to go with this, though, so feel free to ignore or modify any suggestions that make you feel uncomfortable.

Don't bother, there's a Compass plugin that will do it for you. That exact same code is being pulled into the Compass Core for the next release, so soon you wont even need to use a plugin. You get the added advantage that other people will help keep your animations code up-to-date. While you're at it, you can pull in the Compass port of Dan Eden's Animate.css.

Related

CSS animation-delay doesn't work in reactJS with Chrome or Safari

I have three images and some text blocks that I want to display in sequence so that they fade in but start the fade-in at different times.
I have read all the similar issues here but I have not found a solution as yet.
.imgCommunity3 {
max-width: 12.5%;
height: auto;
-webkit-animation-delay: 50s;
-moz-animation-delay: 50s;
-o-animation-delay: 50s;
-ms-animation-delay: 50s;
animation-delay: 50s;
-webkit-animation: fadeIn 15s;
-moz-animation: fadeIn 15s;
-o-animation: fadeIn 15s;
-ms-animation: fadeIn 15s;
animation: fadeIn 15s;
}
I have tried with the animation-delay before and after the fade-in block but it makes no difference. All the blocks appear at the same time - the only difference is that they fade-in at different speeds.
It should be so simple!
I am running on a Mac with Chrome and Safari - it is the same on either browser.

CSS3 animations: transition speed between animations too slow

I've built a slider with the following animations. Unfortunately the transitions between the slides last too long. I haven't found a proper property for setting the speed between switching the slides.
/* Keyframes */
#-webkit-keyframes animation_slides {
0%
{
opacity:0;
}
6%
{
opacity:1;
}
24%
{
opacity:1;
}
30%
{
opacity:0;
}
100%
{
opacity:0;
}
}
/* Animations on my ul li elements */
-webkit-animation-name: animation_slides;
-webkit-animation-duration: 30.0s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: normal;
-webkit-animation-delay: 0;
-webkit-animation-play-state: running;
-webkit-animation-fill-mode: forwards;
&:nth-child(2)
{
-webkit-animation-delay: 6.0s;
-moz-animation-delay: 6.0s;
}
&:nth-child(3)
{
-webkit-animation-delay: 12.0s;
-moz-animation-delay: 12.0s;
}
&:nth-child(4)
{
-webkit-animation-delay: 18.0s;
-moz-animation-delay: 18.0s;
}
&:nth-child(5)
{
-webkit-animation-delay: 24.0s;
-moz-animation-delay: 24.0s;
}
Can you please help me? Thank you very much in advance!
There is no 'speed' per say value, but there is 'duration' and 'delay'. It looks like you can change the value of -webkit-animation-duration: 30.0s; to whatever you wish and correspondingly change all the nth-child -webkit-animation-delays and -moz-animation-delays the same proportion to affect the 'speed' of the transition
For example this would make the transitions half as long:
/* Animations on my ul li elements */
-webkit-animation-name: animation_slides;
-webkit-animation-duration: 15.0s; /* A value I changed */
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: normal;
-webkit-animation-delay: 0;
-webkit-animation-play-state: running;
-webkit-animation-fill-mode: forwards;
&:nth-child(2)
{
-webkit-animation-delay: 3.0s; /* A value I changed */
-moz-animation-delay: 3.0s; /* A value I changed */
}
&:nth-child(3)
{
-webkit-animation-delay: 6.0s; /* A value I changed */
-moz-animation-delay: 6.0s; /* A value I changed */
}
&:nth-child(4)
{
-webkit-animation-delay: 9.0s; /* A value I changed */
-moz-animation-delay: 9.0s; /* A value I changed */
}
&:nth-child(5)
{
-webkit-animation-delay: 12.0s; /* A value I changed */
-moz-animation-delay: 12.0s; /* A value I changed */
}
So long as the proportion between the total duration and nth-child delays stay the same, it will change speed accordingly

Getting Compass to add vendor prefixes to animation selectors

Can anyone tell me how I can get Compass to add the vendor prefixes to CSS3 animation selectors when it compiles? My config file looks like this.
http_path = "/"
css_dir = "/"
sass_dir = "/"
images_dir = "img"
javascripts_dir = "js"
output_style = :expanded
relative_assets = true
line_comments = false
I've tried adding Compass::BrowserSupport.add_support("animation", "webkit", "moz", "ms") to it, but it doesn't work.
Edit
In response to cimmanon's comment, I wanted to avoid having to repeat every selector like this:
.big-wheel {
left: 77px;
bottom: 11px;
-webkit-transform: rotate(0deg);
-webkit-animation-name: wheels;
-webkit-animation-duration: 0.25s;
-webkit-animation-iteration-count: infinite;
-moz-transform: rotate(0deg);
-moz-animation-name: wheels;
-moz-animation-duration: 0.25s;
-moz-animation-iteration-count: infinite;
-ms-transform: rotate(0deg);
-ms-animation-name: wheels;
-ms-animation-duration: 0.25s;
-ms-animation-iteration-count: infinite;
transform: rotate(0deg);
animation-name: wheels;
animation-duration: 0.25s;
animation-iteration-count: infinite;
}
Compass does have a built in mixin for transform
I don't see mixins for the other items documented on the website. Compass makes it easy to write your own if you need to using the experimental mixin.
.foo {
#include experimental('animation-name', wheels, webkit, moz, o, ms, not khtml);
#include experimental('animation-duration', 0.25s, webkit, moz, o, ms, not khtml);
// alternate way of setting prefixes
$animation-support: webkit, moz, o, ms, not khtml;
#include experimental('animation-iteration-count', infinite, $animation-support...);
}
Compiles to:
.foo {
-webkit-animation-name: wheels;
-moz-animation-name: wheels;
-ms-animation-name: wheels;
-o-animation-name: wheels;
animation-name: wheels;
-webkit-animation-duration: 0.25s;
-moz-animation-duration: 0.25s;
-ms-animation-duration: 0.25s;
-o-animation-duration: 0.25s;
animation-duration: 0.25s;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
-ms-animation-iteration-count: infinite;
-o-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
You could try a library like Bourbon. Then in your SCSS file you would only have to write a single include statement, and Bourbon would generate all the prefixes for you on export.
#include transform(translateY(50px));

CSS3 keyframes in stylesheet

I found a nice tutorial on css3 transitions by richard bradshaw which can be found at
http://css3.bradshawenterprises.com/cfimg/
I am trying to set up my Master Page (ASP.Net 4) with a div that has 3 images transitioning
Visual Studio 2010 doesn't like the following keyframes directives AT ALL why? I am set on html5 and css3.
#-webkit-keyframes cf3FadeInOut {
0% {
opacity:1;
}
25% {
opacity:1;
}
75% {
opacity:0;
}
100% {
opacity:0;
}
}
#-moz-keyframes cf3FadeInOut {
0% {
opacity:1;
}
25% {
opacity:1;
}
75% {
opacity:0;
}
100% {
opacity:0;
}
}
Here is the animation code;
.logotransitions img.top {
-webkit-animation-name: cf3FadeInOut;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-iteration-count: infinite;
-webkit-animation-duration: 18s;
-webkit-animation-direction: alternate;
-moz-animation-name: cf3FadeInOut;
-moz-animation-timing-function: ease-in-out;
-moz-animation-iteration-count: infinite;
-moz-animation-duration: 18s;
-moz-animation-direction: alternate;
}
Those are just the animation definitions... you still need to declare that your targeted elements use that animation :
div {
-webkit-animation : cf3FadeInOut 1s ease infinite;
-moz-animation : cf3FadeInOut 1s ease infinite;
animation : cf3FadeInOut 1s ease infinite;
}
By the way, unless you're targeting only webkit & mozilla browsers, you should update your code (definitions & declarations) to include all the browser vendors :
div {
-webkit-animation : cf3FadeInOut 1s ease infinite; /*webkit*/
-o-animation : cf3FadeInOut 1s ease infinite; /*opera*/
-moz-animation : cf3FadeInOut 1s ease infinite; /*mozzila*/
-ms-animation : cf3FadeInOut 1s ease infinite; /*ie*/
animation : cf3FadeInOut 1s ease infinite; /*no vendor*/
}
/*...*/
#-o-keyframes cf3FadeInOut {/*...*/}
/* ... and so on*/

CSS3 Animate: How to have the object not revert to its initial position after animation has run? [duplicate]

This question already has answers here:
Maintaining the final state at end of a CSS animation
(5 answers)
Closed 3 years ago.
I am attempting a simple transform on a shape in CSS (webkit specifically).
The animation runs as expected but upon completion the div will revert to its initial state.
Is there any way to have it remain in its final state?
Heres my CSS thus far:
#-webkit-keyframes rotate-good {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(-90deg);
}
}
#-webkit-keyframes rotate-bad {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(90deg);
}
}
#good-arrow
{
-webkit-animation-name: rotate-good;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: linear;
-webkit-animation-delay: 2s;
}
#bad-arrow
{
-webkit-animation-name: rotate-bad;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: linear;
-webkit-animation-delay: 2s;
}
A briefer way to do this is to add:
-webkit-animation-fill-mode: forwards;
which retains the final keyframe state.
Update: full cross browser
-webkit-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-ms-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
animation-fill-mode: forwards;
the cross-browser solution is:
-webkit-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-ms-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
animation-fill-mode: forwards;
What Madara Uchiha comments above is not always possible for one reason: Imagine instead of starting the animation right away (animation-delay:0s) you want 10 sec of delay before it starts. If so, you would see the final state of your animated element for 10 sec, and then the animation would take it to de 0 keyframe to 100 keyframe transition, but always you are seeing for 10 seconds the ending state.
Oh, that's easy, simply set all the css rules to the finishing result.
Example

Resources