I'm in need of 8 different CSS3 animations which are way too similar, so I used LESS for it. Below is the code, that works perfectly, with one little glitch - the @name variable.
.animation_top (@name, @pxFrom, @pxTo) {
@-moz-keyframes @name {
0% {
top: @pxFrom;
opacity: 0;
}
100% {
top: @pxTo;
opacity: 1;
}
}
@-webkit-keyframes @name {
0% {
top: @pxFrom;
opacity: 0;
}
100% {
top: @pxTo;
opacity: 1;
}
}
@-ms-keyframes @name {
0% {
top: @pxFrom;
opacity: 0;
}
100% {
top: @pxTo;
opacity: 1;
}
}
}
Because css keyframes are started by @ sign, LESS simply ignores the variable of @name. Is there any way how to escape the keyframe @ sign OR to force LESS to somehow render @name properly?
Less version 1.7 now supports a way nicer method:
MIXIN
INPUT
The expected syntax is (vendorprefixed)
(~"@keyframes @{name}") { ... }
. However, the output is incorrect (selectors are merged to@keyframes name 0% { ... } @keyframes name 100% {}
), because the tree syntax of@keyframes
is defined as an exception in less Source code.The idea behind my crafty mixin is to add curly braces through selectors.
(~"@keyframes @{name}{") { ... }
.This renders as:
@keyframes name {{ ... }
{{
does not look well, I add a newline. I was not able to escape the newline directly, so I decided to create a variable@newline: `"\n"`;
. Less parses anything between backticks as JavaScript, so the resulting value is a newline character. Since{ ... }
requires a "selector" to be valid, we pick the first step of the animation,0%
.(~"} dummy") { .. }
. This is ugly, because a useless selector is added.But wait, we already know that vendor-specific prefixes are going to be added in sequence. So, let the final first selector be
(~"@{pre}@@{vendor}keyframes @{name} {@{newline}0%")
.@{pre}
has to be"}@{newline}"
for every keyframes block after the first one.animation-name
is the property to do so. I'm using a guarded mixin to implement this.The solution may look somewhat awkward at first, but it's quite concise.
Is rendered as (notice that the indention inside the keyframes are off by one. This is expected, because Less does not know that we're inside another block, due to the manually added braces).
The following result is confirmed using LESS version 1.3.3 and 1.4.0-b1.
Final notes:
/**/
. Example:(~"..") {/**/}
->.. {/**/}
.Perhaps this is what you want? If you define
@name: "ANIM_NAME";
then I suppose this is the way: