I'm introducing LESS to a large web app project to simplify my CSS. I've got a few CSS rules which apply transitions to a varying number of properties, for example:
.movable {
transition-property: top, left;
transition-duration: 0.2s;
transition-timing-function: ease;
}
.fadeAndStretchable {
transition-property: opacity, width, height, margin;
transition-duration: 1.5s;
transition-timing-function: ease-out;
}
(Note: I've omitted -webkit
, -moz
and -o
properties here for brevity: in reality each of these rules is 12 lines long rather than 3.)
Note that the values for transition-property
are comma-separated. This is unusual in CSS: multiple values are usually space-separated (as in border: 1px solid #f00
). LESS mixins can use the special @arguments
value to produce a space-separated list of all the mixin arguments - but is it possible to define a LESS mixin that takes a variable number of parameters and turns them into a comma-separated value list, suitable for transition-property
?
If necessary, I'm happy with a solution that requires two mixins: one for transition-property
and another for transition-duration
and transition-timing-function
. Here's what I've tried so far:
Attempt 1: using @arguments with unnamed parameters
.transition-property() {
-webkit-transition-property: @arguments;
-moz-transition-property: @arguments;
-o-transition-property: @arguments;
transition-property: @arguments;
}
.movable {
.transition-property(top, left);
}
Result: LESS error ("No matching definition was found for '.transition-property(top, left)'")
Attempt 2: using @arguments with named parameters
.transition-property(@p1, @p2, @p3, @p4, @p5) {
-webkit-transition-property: @arguments;
-moz-transition-property: @arguments;
-o-transition-property: @arguments;
transition-property: @arguments;
}
.movable {
.transition-property(top, left);
}
Result: LESS error ("No matching definition was found for '.transition-property(top, left)'")
Attempt 3: using named parameters with dummy default values
.transition-property(@p1:p1, @p2:p2, @p3:p3, @p4:p4, @p5:p5) {
-webkit-transition-property: @p1, @p2, @p3, @p4, @p5;
-moz-transition-property: @p1, @p2, @p3, @p4, @p5;
-o-transition-property: @p1, @p2, @p3, @p4, @p5;
transition-property: @p1, @p2, @p3, @p4, @p5;
}
.movable {
.transition-property(top, left);
}
Result: No LESS error but it generates a CSS rule -webkit-transition-property: top, left, p3, p4, p5
that the browser ignores because of the unrecognised properties.
I've tried various other approaches (e.g. passing the property as a string 'top,left'
) but all result in the same thing: either a LESS error or invalid CSS.
Is there any way round this? Or do I have to bite the bullet and define a set of mixins overloaded on arity, e.g.
.transition-property(@p1) {...}
.transition-property(@p1, @p2) {...}
.transition-property(@p1, @p2, @p3) {...}
.transition-property(@p1, @p2, @p3, @p4) {...}
etc.
Flexible (LESS 1.5.1+)
This solution does not use any inline javascript and it allows for:
If the number of properties are greater than the number of durations, delays, or timings, then if the
compact
output is set, the final value for duration/delay/timing becomes the value for that parameter for all additional properties beyond the number passed, but ifcompact
is not set, then the long form is output and values are duplicated per browsers interpret ion of the css standards.LESS Mixin
LESS Use Examples
In the above examples, note two things in particular: (1) how the multiple values need to be passed using commas to separate the lists, but semicolons to separate the parameter groups. So to visualize, it is this:
(2) how the
raw-input
example needs an ending semicolon to have it consider the commas as list items:CSS Output of Examples
If long form is never desired then the mixin code can reduce to this:
I've managed to figure it out thanks to Luke Page pointing me towards the
...
syntax.The solution was to use the following:
...
to allow variable parameters~
prefix to escape the resulting expression (i.e. stop LESS from enclosing it in a string)Phew. Here's the resulting mixin:
And here's the full version with a complete set of browser extensions:
Perhaps I am misunderstanding your needs. Why can you not use an escaped string?
Like so:
This is exactly what we use for multi-property transitions. Never had a problem with it.
From less.js 1.3 onwards you have to specify ... in the argument list to signify that more arguments can be added. e.g.