I try to set up this LESS mixin for CSS animation keyframes:
.keyframes(@name, @from, @to) {; @-webkit-keyframes "@name" { from { @from; } to { @to; } } }
but there is some problem with name pharse, is there any option to do this corectly?
The keyframe percentages relate to your animation duration. For example: with a 10 second animation, 10% is the 1 second mark, 50% the 5 second mark, and 100% the 10 second mark.
Right-click (Windows) or Control-click (Mac OS) the keyframe. The keyframe value appears at the top of the context menu that appears. Choose Edit Value to edit the value, if desired. Place the pointer over a keyframe in layer bar mode to see the time and value of the keyframe.
To use keyframes, create a @keyframes rule with a name that is then used by the animation-name property to match an animation to its keyframe declaration.
To create keyframe animations, you need at least two keyframes with different values of the same property. Keyframe animations are formed based on the property change from the start to the end.
Some changes have been made in LESS 1.7 to how directives work, which allows to use variables for the name/keyword of @keyframes
(so the example from the question should work now).
Unfortunately keyframes names can not be dynamically generated in LESS <= 1.6
Hence, the normal way of going about keyframes would use hardcoded names and you would only call for specific "for" and "to" mixins, like this:
.colors-mixin-frame(@from,@to){ from {color: @from;} to {color: @to;} } .width-mixin-frame(@from,@to){ from {width: @from;} to {width: @to;} } // keyframes with hardcoded names calling for specific mixin frames @keyframes red-blue { .colors-mixin-frame(red, blue); } @keyframes change-width { .width-mixin-frame(254px, 512px); }
where you inject the name into the rule name, this however requires an declaration of the next rule that supplies the closing bracket }
at the end of the keyframes declaration. The most convenient is if you just build the animation calling that keyframe
.animation-keyframes(@name, @from, @to, @anim-selector) { @keyf: ~"@keyframes @{name} { `'\n'`from "; @anim: ~"} `'\n'`.@{anim-selector}"; @{keyf} { .from(@name,@from); } to { .to(@name,@to); } @{anim} { animation-name:@name; } }
Note that you also need to define .from(){}
and .to(){}
mixins, and not just use @from
and @to
like you did in your example (because LESS also does not allow for dynamically generated properties) ... this mixins can now construct the desired properties and values ... to use specific property you can use guards or name-specific mixins like these:
// name-specific from and to mixins that are used if first argument equals "colors" .from (colors, @color) { color: @color; } .to (colors, @color) { color: @color; }
Now we can call our mixin in LESS:
// test .animation-keyframes (colors, red, blue, my-colanim);
and get CSS:
@keyframes colors { from { color: #ff0000; } to { color: #0000ff; } } .my-colanim { animation-name: colors; }
this will work also in LESS 1.4, but note that we used javascript interpolation for line breaks, which requires a javascript implementation of LESS.
Edit: to your additional question about prefixes
Here I made two mixins ... one without vendor prefixes and one with them both calling a general .keyframes
mixin:
.keyframes (@name, @from, @to, @vendor:"", @bind:"") { @keyf: ~"@{bind}@@{vendor}keyframes @{name} { `'\n'`from "; @{keyf} { .from(@name,@from); } to { .to(@name,@to); } } .animation-keyframes-novendor (@name, @from, @to, @anim-selector) { .keyframes (@name, @from, @to); @anim: ~"} `'\n'`.@{anim-selector}"; @{anim} { animation-name:@name; } } .animation-keyframes (@name, @from, @to, @anim-selector) { @bind: "} `'\n'`"; .keyframes (@name, @from, @to, "-moz-"); .keyframes (@name, @from, @to, "-webkit-", @bind); .keyframes (@name, @from, @to, "-o-", @bind); .keyframes (@name, @from, @to, "-ms-", @bind); .keyframes (@name, @from, @to, "", @bind); @anim: ~"} `'\n'`.@{anim-selector}"; @{anim} { -moz-animation: @name; -webkit-animation: @name; -o-animation: @name; -ms-animation: @name; animation: @name; } } .from (colors, @color) { color: @color; } .to (colors, @color) { color: @color; } /* keyframes with all vendor prefixes */ .animation-keyframes (colors, red, blue, my-colanim); /* keyframes with no vendor prefix */ .animation-keyframes-novendor (colors, red, blue, my-colanim);
The .animation-keyframes
will now produce keyframes for all vendor prefixes and an animation selector with vendor prefixed properties. And as expected the .animation-keyframes-novendor
gives the same output as the above simple solution (without vendor prefixes).
For your animation to actually work you need to set other animation parameters like timing-function, duration, direction, iteration-count (requires at least a duration time in addition to the name that we already set).
For example:
animation: @name ease-in-out 2s infinite alternate;
If you wrap above mixins in namespaces make sure you change the mixin references inside other mixins to their whole path (including the namespaces).
For example:
#namespace > .keyframes () // see .less source in the demo for details
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With