CSS - Number auto-increasing animation not work in Firefox and Safari - css

I am trying to implement an auto-increasing number animation by CSS following this article.
It works well in my application when opening in Chrome, but in Firefox and Safari, it always shows 0.
Do you have any idea about this problem? Here's the snippet:
#property --num {
syntax: "<integer>";
initial-value: 0;
inherits: false;
}
div {
animation: counter 5s infinite alternate ease-in-out;
counter-reset: num var(--num);
font: 800 40px system-ui;
padding: 2rem;
}
div::after {
content: counter(num);
}
#keyframes counter {
from {
--num: 0;
}
to {
--num: 100;
}
}
<div></div>

According to https://autoprefixer.github.io/ it should be like this:
/*
* Prefixed by https://autoprefixer.github.io
* PostCSS: v8.4.14,
* Autoprefixer: v10.4.7
* Browsers: last 4 versions
*/
#property --num {
syntax: "<integer>";
initial-value: 0;
inherits: false;
}
div {
-webkit-animation: counter 5s infinite alternate ease-in-out;
animation: counter 5s infinite alternate ease-in-out;
counter-reset: num var(--num);
font: 800 40px system-ui;
padding: 2rem;
}
div::after {
content: counter(num);
}
#-webkit-keyframes counter {
from {
--num: 0;
}
to {
--num: 100;
}
}
#keyframes counter {
from {
--num: 0;
}
to {
--num: 100;
}
}

Related

Multiple animation keyframes doesn't work

#keyframes showAnimation {
to {
opacity: 1;
}
}
#keyframes ellipsis {
to {
width: 20px;
}
}
#keyframes hide {
to {
display: none;
}
}
#mixin points {
overflow: hidden;
display: inline-block;
vertical-align: bottom;
content: '\2026';
width: 0px;
}
.findingAvailableRobot {
opacity: 0;
animation: showAnimation 3s 1s forwards;
&:after {
#include points;
animation: ellipsis steps(4, end) 900ms infinite, hide 0s 4s forwards;
}
}
findingAvailableRobot I'm trying to make anymation loading process , but also I want to stop this animation after some time , I've found that animation can take multiple keyframes , but it doesn't work , want to hide :after , after 4s seconds . Is it possible ? Or what I do wrong ?

SCSS particles animation - create at random position, but move all particles in the same direction

I'm fairly new to SCSS so hopefully someone can help me out.
I'm trying to move particles in the same direction (down), but because all the particles are placed randomly their destination also ends up random.
I would like to keep random placement, but once they are placed I want them all going in the same direction (down) and not in the random direction. I don't know how to do that without loosing random positioning generated with steps.
I know how to do this in CSS, but that would require specifying every path manually, which will be my final solution if I can get it to work with SCSS, unless someone can help me out?
Here is JSFiddle to show how it's behaving, but this is the part where random steps are created:
SCSS
#for $i from 1 through $dot-count {
&:nth-of-type(#{$i}) {
animation-name: move-path-#{$i};
&:before {
animation-duration: random(5000) + 5000ms, random(1000) + 7000ms;
animation-delay: random(6000) + 500ms, 0s;
}
}
$steps: random(15) + 10;
#keyframes move-path-#{$i} {
#for $step from 0 through $steps {
#{$step / $steps * 100%} {
transform: translateX(random(100) - 50vw)
translateY(random(100) - 50vh)
scale(random(70) / 100 + 0.3);
}
}
}
}
You could define a random variable common to all your particles, use it to position your particles and then move them according to their step number and not randomly.
html {
font-size: 30vmax / 1920 * 100;
font-family: "Quicksand", sans-serif;
background-color: #000;
margin: 0;
padding: 0;
#media (max-width: 768px) {
font-size: 50px;
}
}
// Stars
$dot-color: #fff;
$dot-count: 35;
#milky-way {
width: 100%;
}
.sky {
position: fixed;
width: 100%;
height: 100%;
z-index: 10;
pointer-events: none;
}
.dot {
position: absolute;
width: 0.08rem;
height: 0.08rem;
top: 50%;
left: 50%;
animation: 160s ease both infinite alternate;
&:before {
content: "";
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: $dot-color;
transform-origin: -1rem;
animation: lighting ease both infinite, auto-rotating ease both infinite;
}
#for $i from 1 through $dot-count {
// Random variable common to all particles
$random: random(100);
&:nth-of-type(#{$i}) {
animation-name: move-path-#{$i};
&:before {
animation-duration: random(5000) + 5000ms, random(1000) + 7000ms;
animation-delay: random(6000) + 500ms, 0s; // less than max duration
}
}
$steps: random(15) + 10;
#keyframes move-path-#{$i} {
#for $step from 0 through $steps {
#{$step / $steps * 100%} {
// first translation is depending on a common random, second is depending on the step number
transform: translateX($random - 50vw) translateX($step * $step * 150px)
translateY($random - 50vh) translateY($step * $step * 150px)
scale(random(70) / 100 + 0.3);
}
}
}
}
}
#keyframes lighting {
0%,
30%,
100% {
opacity: 0;
}
5% {
opacity: 1;
box-shadow: 0 0 0.3rem 0.05rem $dot-color;
}
}
#keyframes auto-rotating {
to {
transform: rotate(0deg);
}
}

Animating :after in css

Im trying to figure out why this simple code isn't working.
http://jsfiddle.net/yq1ro6n5/
#keyframes testing {
from: {font-size: 42px;}
to: {font-size: 64px;}
}
a:after {
content: "Hello!";
animation: testing 1s infinite;
}
-
<a></a>
Can anyone explain?
Remove : from the keyframe like this
#keyframes testing {
from {
font-size: 42px;
}
to {
font-size: 64px;
}
}
a {
}
#keyframes testing {
from {
font-size: 42px;
}
to {
font-size: 64px;
}
}
a:after {
content:"Hello!";
animation: testing 3s infinite;
}
<a></a>

How do I loop a css animation with multiple keyframe definitions?

The Issue
I have two css keyframe animations which I am running on a single element:
.fade-bg {
animation-name: fade-bg-1, fade-bg-2;
animation-delay: 0, 6s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
The animations are defined as such:
#keyframes fade-bg-1 {
from {
opacity: 0;
background-image: url(image-1.jpg);
}
50% {
opacity: 1;
background-image: url(image-1.jpg);
}
to {
opacity: 0;
background-image: url(image-1.jpg);
}
}
#keyframes fade-bg-2 { /* Same as fade-bg-1 only with image-2.jpg */ }
The above works but when it gets to the second animation, it keeps repeating only that animation and does not loop back to fade-bg-1.
I've tried many different combinations of animation-direction but to no avail.
The Question
How do I make it so that the animation returns to fade-bg-1 and repeats itself?
The Example
EXAMPLE
Without javascript I don't think you can. However you can achieve the same effect using a single keyframe animation.
.fade-bg {
animation-name: fade-bg;
animation-delay: 0;
animation-iteration-count: infinite;
animation-direction: forward;
}
#keyframes fade-bg {
0% {
opacity: 0;
background-image: url('image-1.jpg');
}
25% {
opacity: 1;
background-image: url('image-1.jpg');
}
50% {
opacity: 0;
background-image: url('image-1.jpg');
}
51% {
opacity: 0;
background-image: url('image-2.jpg');
}
75% {
opacity: 1;
background-image: url('image-2.jpg');
}
100% {
opacity: 0;
background-image: url('image-2.jpg');
}
}
EXAMPLE
I'm not sure this is possible with just css, but if you set up a setInterval method in JS cleverly, you could probably simulate the same thing by splitting the class into two.
var index = 1;
function switchBackground() {
if (index == 1) {
//this switches to the first background
var div = document.getElementById("yourDiv");
div.className = "fade-bg-1";
index = 0;
}
else {
//this switches to the second background
var div = document.getElementById("yourDiv");
div.className = "fade-bg-2";
index = 1;
}
}
setInterval(switchBackground(), 6000);
With .fade-bg-1 and .fade-bg-2 being the two animation classes.
Here's a jsfiddle if you want to play with it.
I asked this question almost 6 years ago, much has changed but no real solution with pure css.
The closest I could come up with was using a pseudo element to apply the second animation to.
Possible Solution:
Use a pseudo element like ::after and apply the second animation to it.
Code:
.animation--fade-bg, .animation--fade-bg::after {
width: 500px;
height: 500px;
background-size: cover;
background-position: 50%;
background-repeat: no-repeat;
animation-iteration-count: infinite;
animation-duration: 3s;
}
.animation--fade-bg::after {
content: "";
display: block;
animation-direction: reverse;
}
.animation--fade-bg-1 {
animation-name: fade-bg-1;
}
.animation--fade-bg::after {
animation-name: fade-bg-2;
}
#keyframes fade-bg-1 {
from {
opacity: 0;
background-image: url('http://i.imgur.com/sRnvs0K.jpg');
}
50% {
opacity: 1;
background-image: url('http://i.imgur.com/sRnvs0K.jpg');
}
to {
opacity: 0;
background-image: url('http://i.imgur.com/sRnvs0K.jpg');
}
}
#keyframes fade-bg-2 {
from {
opacity: 0;
background-image: url('http://i.imgur.com/wL4RT1w.jpg');
}
50% {
opacity: 1;
background-image: url('http://i.imgur.com/wL4RT1w.jpg');
}
to {
opacity: 0;
background-image: url('http://i.imgur.com/wL4RT1w.jpg');
}
}
<div class="animation--fade-bg animation--fade-bg-1"></div>

LESS CSS Pass mixin as a parameter to another mixin

Is there any way to pass one mixin or style's declaration to another mixin as an input parameter?
Let's take a look at an example with animation keyframes. Following is how we define keyframes in pure CSS:
#-moz-keyframes some-name
{
from { color: red; }
to { color: blue; }
}
#-webkit-keyframes some-name
{
from { color: red; }
to { color: blue; }
}
#keyframes some-name
{
from { color: red; }
to { color: blue; }
}
Idea is to simplify these declarations using mixins, so we can have something like following:
.keyframes(name, from, to)
{
// here we need somehow to reproduce structure
// that we have in an example above
}
// define one animation
.my-from() { color: red; }
.my-to() { color: blue; }
// the following won't work because you cannot pass mixin as a parameter
// in way I have here, so I am looking for a way to solve this problem
.keyframes('some-name', .my-from, .my-to);
// define another animation
.another-from() { font-size: 1em; }
.another-to() { font-size: 2em; }
.keyframes('another-name', .another-from, .another-to);
The system will have different modules that could be dynamically attached to application as well as removed. So, don't suggest me to use #import because it's not the case. Output CSS is dynamically compiled on-fly using information about modules and their own LESS styles as well as base LESS dependencies like mixins library and etc.
Note: it will work for me if you know a way to pass class definition instead of mixin. In an example above it would be .my-from instead of .my-from() and etc.
UPDATED for LESS 1.7.0+ (WAY Simpler)
We can do this far more directly now with the 1.7.0 update and the ability to create rulesets, and to use variables in setting #keyframes.
Now we really can pass a mixin through a parameter by a ruleset, or we can pass in the property stings themselves. So consider this:
LESS (using 1.7)
.keyframes(#name, #from, #to) {
#frames: {
from { #from(); }
to { #to(); }
};
#pre: -moz-keyframes;
#-moz-keyframes #name
{
#frames();
}
#-webkit-keyframes #name
{
#frames();
}
#keyframes #name
{
#frames();
}
}
.keyframes(testName, {color: red; .myMix(0);}, {color: blue; .myMix(1);});
.myMix(#value) {opacity: #value;}
Note that I am passing both a property setting and a mixin call, and my output is:
CSS Output
#-moz-keyframes testName {
from {
color: red;
opacity: 0;
}
to {
color: blue;
opacity: 1;
}
}
#-webkit-keyframes testName {
from {
color: red;
opacity: 0;
}
to {
color: blue;
opacity: 1;
}
}
#keyframes testName {
from {
color: red;
opacity: 0;
}
to {
color: blue;
opacity: 1;
}
}
Note how the rulesets are passed, in brackets {...}, and then called, via #from() and #to() (looking a lot like a mixin call). I'm using these passed rule sets to set another ruleset of #frames which is then itself called to fill the keyframes definitions.
More Generically
Here I pass a private mixin to another mixin and then call it from that other mixin:
LESS
.someMixin(#class; #expectedMixin) {
.#{class} {
#expectedMixin();
.myPrivateMix(0.6);
test: 1;
}
}
.someMixin(newClass; {.myClass;});
.myClass {
.myPrivateMix(#value) {opacity: #value;}
}
CSS Output
.newClass {
opacity: 0.6;
test: 1;
}
Kept the below for legacy info.
Updated (added LESS 1.4.0+ support)
Wow, this took some doing, but I think I have something you can work with. However, it does take some special defining of your mixins in your modules, specifically, using pattern matching. So...
First, Define Your Module Mixins
Note how the module mixins intended to be used in a specific future mixin are defined with the same mixin name, but with a different pattern name. This was key to making this work.
// define one animation in a module
.from(my-from){ color: red; }
.to(my-to) { color: blue; }
// define one animation in another module
.from(another-from){ font-size: 1em; }
.to(another-to) { font-size: 2em; }
If you also want individual mixin names in the modules, you should be able to do this:
// define one animation in a module
.my-from(){ color: red; }
.my-to() { color: blue; }
.from(my-from){ .my-from() }
.to(my-to) { .my-to() }
// define one animation in another module
.another-from(){ font-size: 1em; }
.another-to() { font-size: 2em; }
.from(another-from){ .another-from() }
.to(another-to) { .another-to() }
This should allow one to call either the straight mixin .my-from() or, to make it variably accessible within later mixins that access the singular .from() mixin group through the pattern matching.
Next, Define Your Mixin
For your #keyframes example, that was extremely difficult. In fact, a stack overflow answer was vital to helping me solve an issue with applying the #name, which was not applying under normal LESS rules because of it following the #keyframes definition. The solution to apply the #name looks nasty, but it works. It does have the, perhaps, unfortunate necessity of also defining a selector string to play the animation by (because it uses that string to help build the last } of the keyframes). This naming limitation would only be true of css strings that begin with # like #keyframes and probably #media.
Further, because we have a standard mixin name used in our module files, we can access that consistently within our new mixin, while at the same time passing a variable in to select the proper variation of that mixin through a pattern match. So we get:
LESS 1.3.3 or under
// define mixin in mixin file
.keyframes(#selector, #name, #from, #to) {
#newline: `"\n"`; // Newline
.setVendor(#pre, #post, #vendor) {
(~"#{pre}##{vendor}keyframes #{name} {#{newline}from") {
.from(#from);
}
to {
.to(#to);
}
.Local(){}
.Local() when (#post=1) {
(~"}#{newline}#{selector}") {
-moz-animation: #name;
-webkit-animation: #name;
-o-animation: #name;
-ms-animation: #name;
animation: #name;
}
}
.Local;
}
.setVendor("" , 0, "-moz-");
.setVendor(~"}#{newline}", 0, "-webkit-");
.setVendor(~"}#{newline}", 0, "-o-");
.setVendor(~"}#{newline}", 0, "-ms-");
.setVendor(~"}#{newline}", 1, "");
}
LESS 1.4.0+
.keyframes(#selector, #name, #from, #to) {
#newline: `"\n"`; // Newline
.setVendor(#pre, #post, #vendor) {
#frames: ~"#{pre}##{vendor}keyframes #{name} {#{newline}from";
#{frames} {
.from(#from);
}
to {
.to(#to);
}
.Local(){}
.Local() when (#post=1) {
#animationSector: ~"}#{newline}#{selector}";
#{animationSector} {
-moz-animation: #name;
-webkit-animation: #name;
-o-animation: #name;
-ms-animation: #name;
animation: #name;
}
}
.Local;
}
.setVendor("" , 0, "-moz-");
.setVendor(~"}#{newline}", 0, "-webkit-");
.setVendor(~"}#{newline}", 0, "-o-");
.setVendor(~"}#{newline}", 0, "-ms-");
.setVendor(~"}#{newline}", 1, "");
}
Now Call Your Mixin
You can give it your own name, and just pass the straight pattern (all are no dot [.] and no quotes) for the pattern matches on the module mixins, but don't forget that you also need a selector string (which is quoted) to get the mixin to work right:
.keyframes('.changeColor', some-name, my-from, my-to);
.keyframes('.changeFontSize', another-name, another-from, another-to);
Which Gives You the Desired Output
#-moz-keyframes some-name {
from {
color: red;
}
to {
color: blue;
}
}
#-webkit-keyframes some-name {
from {
color: red;
}
to {
color: blue;
}
}
#-o-keyframes some-name {
from {
color: red;
}
to {
color: blue;
}
}
#-ms-keyframes some-name {
from {
color: red;
}
to {
color: blue;
}
}
#keyframes some-name {
from {
color: red;
}
to {
color: blue;
}
}
.changeColor {
-moz-animation: some-name;
-webkit-animation: some-name;
-o-animation: some-name;
-ms-animation: some-name;
animation: some-name;
}
#-moz-keyframes another-name {
from {
font-size: 1em;
}
to {
font-size: 2em;
}
}
#-webkit-keyframes another-name {
from {
font-size: 1em;
}
to {
font-size: 2em;
}
}
#-o-keyframes another-name {
from {
font-size: 1em;
}
to {
font-size: 2em;
}
}
#-ms-keyframes another-name {
from {
font-size: 1em;
}
to {
font-size: 2em;
}
}
#keyframes another-name {
from {
font-size: 1em;
}
to {
font-size: 2em;
}
}
.changeFontSize {
-moz-animation: another-name
-webkit-animation: another-name;
-o-animation: another-name;
-ms-animation: another-name;
animation: another-name;
}
Simplification
I just simplified a little ScottS' way, separateing #keframes from -animation:
.keyframes(#name, #from, #to) {
#newline: `"\n"`;
.Local(#x){};
.Local(#x) when (#x="") {(~"}#{newline}/*"){a:a}/**/};
.setVendor(#pre, #vendor) {
(~"#{pre}##{vendor}keyframes #{name} {#{newline}from") {
.from(#from);
}
to {
.to(#to);
}
.Local(#vendor);
}
.setVendor("" , "-webkit-");
.setVendor(~"}#{newline}", "-moz-");
.setVendor(~"}#{newline}", "-o-");
.setVendor(~"}#{newline}", "");
}
.animation(...) {
-webkit-animation: #arguments;
-moz-animation: #arguments;
-o-animation: #arguments;
animation: #arguments;
}
use:
.from(a1-from){ width: 10px; }
.to(a1-to) { width: 20px; }
.keyframes(a1-animation, a1-from, a1-to);
.selector {
// some other css
.animation(a1-animation 1s infinite linear);
}
output:
#-webkit-keyframes a1-animation {
from {
width: 10px;
}
to {
width: 20px;
}
}
#-moz-keyframes a1-animation {
from {
width: 10px;
}
to {
width: 20px;
}
}
#-o-keyframes a1-animation {
from {
width: 10px;
}
to {
width: 20px;
}
}
#keyframes a1-animation {
from {
width: 10px;
}
to {
width: 20px;
}
}
/* {
a: a;
}
/**/
.selector {
// some other css
-webkit-animation: a1-animation 1s infinite linear;
-moz-animation: a1-animation 1s infinite linear;
-o-animation: a1-animation 1s infinite linear;
animation: a1-animation 1s infinite linear;
}
little problem:
So animation is now separated from #keyframes, but we got to pay the price. There is a nasty:
/* {
a: a;
}
/**/
but it shouldn't be a problem -> propably all of us push CSS files through any kinds of minifiers which cut comments out.
You can also use my solution to generate CSS keyframes: https://github.com/thybzi/keyframes
Features:
Cross-browser keyframes generation (Firefox 5+, Chrome 3+, Safari 4+, Opera 12+, IE 10+)
Up to 16 timepoints in each keyframes rule (and the number can be easily augmented, if needed)
Mixins, variables and functions can be used for styling timepoints
Keyframes are created separately from animation rules, so:
multiple animation rules can use the same keyframe with different values for timing, repeating, etc,
multiple animations can be used within same animation rule
animations can be applied (not created!) inside any parent selector
Lightweight and (almost) neat LESS code
Basic usage:
// Preparing styles for animation points
.keyframes-item(fadeIn, 0%) {
opacity: 0;
}
.keyframes-item(fadeIn, 100%) {
opacity: 1;
}
// Generating keyframes
.keyframes(fadeIn);
// Applying animation to fade-in block in 1.5 seconds
.myBlock {
.animation(fadeIn 1.5s);
}
Its not really how you would use mixins.
You should do something along the lines of:
.mixin-one { ... }
.mixin-two { ... }
.target-style {
.mixin-one;
.mixin-two;
font-family: 'Comic Sans MS';
color: magenta;
}

Resources