I am trying to create a mixin that dynamically defines variables in LESS CSS, by actually assigning them a composite name.
The simplified use-case (not the real one):
.define(@var){
@foo{var}: 0;
}
Then one would call the mixin as such:
.define('Bar'){
@fooBar: 0;
}
Since this kind of string interpolation is possible while using selectors names, I was wondering if the same would be possible for variable names; so far, I have had no luck with various syntaxes I tried (other than the above, I tried escaping, quoting, using the ~
prefix and so on).
I just tried one more thing, and I feel I might be close; but I am experiencing an oddity of the LESS syntax. If I write this:
.define(@var){
#namespace {
@foo: @var;
}
}
And then call it like so:
.define(0)
I can then use @foo
in the usual namespaced fashion:
.test {
#namespace;
property: @foo; /* returns 0 */
}
However, the same doesn't apply in the case of a string-interpolated selector:
.define(@var, @ns){
#@{ns} {
@foo: @var;
}
}
.define(0, namespace);
.test {
#namespace;
property: @foo;
}
The above code gives me the following error:
Name error: #namespace is undefined
However, the string interpolation was successful and valid. As a matter of fact, if I take away the .test
part and modify the above to output a test property, I can see that the CSS is parsed correctly. I mean:
.define(@var, @ns){
#@{ns} {
@foo: @var;
prop: @foo;
}
}
.define(0, namespace);
Outputs the following CSS:
#namespace {
prop: 0;
}
What you desire to do is not currently possible in LESS. I can think of two possible "workarounds" if you know ahead of time what variable names you want to allow to be used (in other words, not fully dynamic). Then something like one of the following could be done:
.define(@var) {
@fooBar: 0;
@fooTwo: 2;
@fooYep: 4;
@fooSet: 'foo@{var}';
}
.define(Two);
.test {
.define(Bar);
prop: @@fooSet;
}
.test2 {
prop: @@fooSet;
}
LESS
.define(@var) {
.foo() when (@var = Bar) {
@fooBar: 0;
}
.foo() when (@var = Two) {
@fooTwo: 2;
}
.foo() when (@var = Yep) {
@fooYep: 4;
}
.foo();
}
.define(Two);
.test {
.define(Bar);
prop: @fooBar;
}
.test2 {
prop: @fooTwo;
}
.test {
prop: 0;
}
.test2 {
prop: 2;
}
But I'm not sure how useful either would really be, nor do I know if it could have any real application in your actual use case (since you mention the above is not the real use case). If you want a fully dynamic variable in LESS, then it cannot be done through LESS itself.