I'm relatively new to LESS. It's impressive, and I'm really enjoying working with it thus far, but I'm curious to know: Can I use results produced by mixin functions and concatenate them with strings. I'm including an example with LESShat, which offers a number of Mixin Functions, including a function that generates keyframe animations. The issue being that the Keyframe function needs to be passed a string including properties, and I'm wanting to use other mixins from the LESShat library instead of css properties to generate such keyframe animations.
Original .less File:
#import "css/lesshat.less";
.keyframes(~'myskew, from {.skew(0)} to {.skew(90)}');
.myskewclass {
.animation(myskew 3s linear alternate)
}
Resulting .css File:
lesshat-selector{-lh-property:0}
#-webkit-keyframes myskew{from{.skew(0)}to{.skew(90)}}
#-moz-keyframes myskew{from{.skew(0)}to{.skew(90)}}
#-o-keyframes myskew{from{.skew(0)}to{.skew(90)}}
#keyframes myskew{from{.skew(0)}to{.skew(90)}}
.myskewclass{
-webkit-animation:myskew 3s linear alternate;
-moz-animation:myskew 3s linear alternate;
-o-animation:myskew 3s linear alternate;
animation:myskew 3s linear alternate
}
Obviously not quite what I was going for as the keyframe animations still contain the skew functions and not the values returned by the skew functions. I believe the problem may be that I'm trying to pass other mixins from LESShat inside of the string. So, is there some manner of concatenating strings and mixin functions in LESS? Keep in mind, I'm a total NEWB to LESS. I would simply rather not have to write my own cross-browser transforms. It'd me cool if it could all be automated using LESS. I'm obviously doing it wrong.
The following link describes the .keyframes and .skew functions from LESShat, but I see nothing regarding the mixing of the two mentioned. Maybe I somehow missed that part.
https://github.com/madebysource/lesshat/blob/master/README.md
As far as i understand you should not use the skew() mixin inside or together with keyframes mixin, according the docs you mention, you should use:
.keyframes(~'animationName, 0%{ transform: skewX(0); } 100%{ transform: skewX(90deg) }');
The above will output the following CSS code:
lesshat-selector {
-lh-property: 0; }
#-webkit-keyframes animationName{ 0%{ -webkit-transform: skewX(0); } 100%{ -webkit-transform: skewX(90deg) }}
#-moz-keyframes animationName{ 0%{ -moz-transform: skewX(0); } 100%{ -moz-transform: skewX(90deg) }}
#-o-keyframes animationName{ 0%{ -o-transform: skewX(0); } 100%{ -o-transform: skewX(90deg) }}
#keyframes animationName{ 0%{-webkit-transform: skewX(0);-moz-transform: skewX(0);-ms-transform: skewX(0);transform: skewX(0); } 100%{-webkit-transform: skewX(90deg);-moz-transform: skewX(90deg);-ms-transform: skewX(90deg);transform: skewX(90deg);};
}
You should also notice that using the autoprefixer instead of mixin libraries such as Lesshat will be better practice in most cases.
You should run:
npm install less
npm install less-plugin-autoprefix
less input.less --autoprefix
With the autoprefix plugin:
#keyframes myskew {
0% {
transform: skewX(0);
}
100% {
transform: skewX(90deg);
}
}
Compiles into:
#-webkit-keyframes myskew {
0% {
-webkit-transform: skewX(0);
transform: skewX(0);
}
100% {
-webkit-transform: skewX(90deg);
transform: skewX(90deg);
}
}
#keyframes myskew {
0% {
-webkit-transform: skewX(0);
transform: skewX(0);
}
100% {
-webkit-transform: skewX(90deg);
transform: skewX(90deg);
}
}
Related
I want to use https://animate.style/. But it's more than 90 KBs in size.
I just want a very simple bouncing animation. That's all.
Apart from going into the source code and trying to recreate the bouncing keyframes and animations, is there another way to do so?
For example, in Material UI, or in TailwindCSS only what you have used would be included in the final bundle.
Is there something similar for Animate.css too?
If you only need a simple bouncing animation, why not using your own keyframes?
Exemple falling down :
#keyframes myAnim {
0% {
animation-timing-function: ease-in;
opacity: 1;
transform: translateY(-45px);
}
75% {
transform: translateY(10px);
}
100% {
transform: translateY(0px);
}
}
#my_little_square {
width:50px;
height:50px;
background-color:#f00;
animation: myAnim 1s ease 0s 1 normal forwards;
}
<div id="my_little_square">
</div>
Here is a little tool to help you start : https://webcode.tools/generators/css/keyframe-animation
I'm trying to animate some shapes made with CSS-Doodle which will be a part of my background. Basically, I want them to always float around the screen and always rotate but I want the two animations at different speeds.
With the code below I can only get either one to work by switching around the order of chaining.
animation: spin #r(3s, 10s) infinite, flow #r(20s, 40s) infinite linear;
#keyframes flow {
0%, 100%{
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0)
}
50% {
-webkit-transform: translate3d(#r(-500%, 1000%), #r(-500%, 1000%), 0);
transform: translate3d(#r(-500%, 1000%), #r(-500%, 1000%), 0);
}
}
#keyframes spin {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
I'm hoping there's a way for both of them to be applied at the same time even if it's not pure CSS.
There's probably a better way but the simplest solution would be to put a wrapper around the element so that the wrapper gets one animation and the actual element gets the other animation.
I have a property #keyframes, I compiled with autoprefixer to add the needed prefixes.
What I would like to do, is to add an argument to the animation name (or wherever is possible) to change a value of properties into the keyframes key.
This is what I have right now :
#keyframes loader {
0% { transform: translate(0, -50%) rotate(0deg); }
100% { tranform: translate(0, -50%) rotate(360deg); }
}
And basically what I would like to do :
#keyframes loader(#transform) {
0% { transform: #transform rotate(0deg); }
100% { tranform: #transform rotate(360deg); }
Passing arguments to #keyframes cannot be done directly in Less. We can however wrap the whole #keyframes rule within a parent mixin, pass the argument to that mixin and use it within the frames.
.loader(#transform){ /* wrapper mixin which accepts input parameter */
#keyframes loader {
0% { transform: #transform rotate(0deg); }
100% { transform: #transform rotate(360deg); }
}
}
.loader(translate(0, -50%)); /* mixin call */
(Curt had provided an answer initially but had deleted it for reasons unknown to me.)
Just in case you are interested, generic keyframe mixins can also be written in Less like given below.
Sample 1:
.generickeyframe(#name; #from; #to){ /* takes name, from frame rules, to frame rules */
#keyframes #name{
0% { #from();}
100% { #to();}
}
}
.generickeyframe(loader; {transform: translate(0,-50%) rotate(0deg)};
{transform: translate(0,-50%) rotate(360deg)});
Sample 2:
.keyframefromto(#name; #from; #to){
#keyframes #name{
0% { transform: #from;}
100% { transform: #to;}
}
}
.keyframefromto(loader; translate(0,-50%) rotate(0deg); translate(0,-50%) rotate(360deg));
If multiple frames are required to be present within the #keyframes rule, we could make use of array-list and loops like in the below snippet. This mixin takes the name of the animation, the list of frames (their percentage numbers) and the properties for each frame (in the form of rulesets) as parameters.
.generickeyframe(#name; #framelist; #frameprops){
#keyframes #name{
.loop-framelist(#index) when (#index <= length(#framelist)){
#framepos: extract(#framelist, #index) * 1%;
#{framepos}{
#props: extract(#frameprops, #index);
#props();
}
.loop-framelist(#index + 1);
}
.loop-framelist(1);
}
}
.generickeyframe(loader;
0,25,50,75,100;
{transform: translateX(10px);},
{transform: translateX(20px);},
{transform: translateX(50px);},
{transform: translateX(20px);},
{transform: translateX(10px);}
);
Compiled CSS:
#keyframes loader {
0% {transform: translateX(10px);}
25% {transform: translateX(20px);}
50% {transform: translateX(50px);}
75% {transform: translateX(20px);}
100% {transform: translateX(10px);}
}
This question was orginally related to FontAwesome, but is a general firefox problem.
So i'm using the class fa-spin that will spin the icon, here you can find some examples of it.
Here is the spinning css file:
// Spinning Icons
// --------------------------
.#{$fa-css-prefix}-spin {
-webkit-animation: spin 2s infinite linear;
-moz-animation: spin 2s infinite linear;
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
animation: spin 2s infinite linear;
}
#-moz-keyframes spin {
0% { -moz-transform: rotate(0deg); }
100% { -moz-transform: rotate(359deg); }
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(359deg); }
}
#-o-keyframes spin {
0% { -o-transform: rotate(0deg); }
100% { -o-transform: rotate(359deg); }
}
#-ms-keyframes spin {
0% { -ms-transform: rotate(0deg); }
100% { -ms-transform: rotate(359deg); }
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(359deg); }
}
Now all works fine in chrome and IE10, however it doesn't in firefox :
jsFiddle.
When you run it for the first time it looks just good, but try the interact with the site(for example: scroll or run the script again in jsFiddle). The animation becomes all jittery. I have no idea what could cause this strange behavior, hope that anyone could help me.
Edit
The problem occurs on Windows 7 32-bit and 25.0 version of Firefox(No add-ons).
However it does work at my home PC, where it also has Windows 7 32-bit 25.0 firefox.
An preview how it looks on my screen:
Note that it works for the first couple of seconds but after it will get jittery (this stuttering is because my .gif is bad).
See my answer for more information
Before you want to add this 'hack', you should first try to update your driver
What i did notice is that IE and Chrome actually makes the text blurry, which FF doesn't. I thought of using the blur filter, but that didn't work. Also the font width didn't stayed the same, so i needed something that or reminded the client of his width or force the width to be static at all time.
I came across the SVG filter XML url, that was special for Firefox 10+ and Firefox on android. I tryed to apply this to my element and my problem was completly gone!
i did use <feColorMatrix type=saturate values=1/> so the saturate filter didn't take away the colors.
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'saturate\' values=\'1\'/></filter></svg>#grayscale");
When adding this to the .fa-spin class that FontAwesome uses, it'll work on every spinning element.
jsFiddle
The platform were I work does not support #keyframes because of security reasons with the #.
My question is if I can replace it with some other css trick.
For example I have this code:
.cubo {
animation:giro 25s infinite linear;
}
#keyframes giro {
0% {transform: rotateX(0deg) rotateY(0deg);}
100% {transform: rotateX(1080deg) rotateY(360deg);
}
}
Can I replace it with transitions or transforms to avoid using the #? (no javascript supported either).
You could instead make it a transition by multiplying the transition duration, rotateX, and rotateY values all by a common factor x and applying the transition class on page load. In my example I multiplied them by 40, but you can go as high as you want but I wouldn't go too high because the processor might overload at some point and break the page. This runs for 1000 seconds, not many people will stay on a page past that
Here is a live demo of that approach
/* CSS */
.cubo {
/* ...Your other code... */
transition: all 1000s linear;
}
.animate {
-webkit-transform: rotateX(43200deg) rotateY(14400deg);
-moz-transform: rotateX(43200deg) rotateY(14400deg);
-o-transform: rotateX(43200deg) rotateY(14400deg);
-ms-transform: rotateX(43200deg) rotateY(14400deg);
transform: rotateX(43200deg) rotateY(14400deg);
}
/* Javascript (ran on page load) */
document.getElementsByClassName('cubo')[0].classList.add('animate');