Reputation: 308
I needed to create a function for some big color work on my Bootstrap variables. Unfortunately LESS doesn't allow you to create functions that can be called like theirs (ex. @myvar: darken(@color, 20%);).
The option provided on the doc site is to use a mixin that returns a variable. This worked well for me when I used it where the variable was declared as the property value, but I need to run my new mixin on many variables in the Bootstrap variable.less file. If I call the mixin multiple times there, it always returns the first color.
Part that works:
.mixin(@color) {
@var: @color;
}
.caller-1 {
.mixin(blue);
color:@var;
}
.caller-2 {
.mixin(red);
color:@var;
}
CSS
.caller-1 {
color:blue;
}
.caller-2 {
color:red;
}
What does not work:
.mixin(blue);
@color-1: @var; // My value is now blue
.mixin(red);
@color-2: @var; // My value is also blue
I thought I could get around this by building a unique variable in the mixin, but I can't find anyway to build one.
.mixin(@color; @num)
@var+@{num}: @color;
}
.mixin(blue; 1);
@color-1: @var1;
.mixin(red; 2);
@color-2: @var2;
Any idea on how to create a variable name in a mixin or other ideas on how to make one work like the LESS functions?
Upvotes: 1
Views: 249
Reputation: 23627
Variables are actually constants, and their scope is based only on context (where they appear in the block doesn't matter). It's only different when you call it within a selector block because of context. When you call the mixin at top-level, you define @var
once for that level and it won't be overriden.
If you have to use variables, I suggest you try to find a solution taking advantage of the context. For example, you might be able to try something with mixin guards (it's actually even simpler, as @seven-phases-max commented below). This is a way to run a mixin outside the context of a selector but still inside a context (updated example):& when(condition) {...}
& {
.mixin(red);
.test1 { color: @var; }
}
& {
.mixin(blue);
.test1 { color: @var; }
}
You actually can define functions that will be called using Less by your Less runtime, but they can't be defined using Less. This is possible if you run your processor using Node.js, for example. But it's quite a hack and not trivial since you have to write them in JavaScript and wrap values in undocumented less.js
types.
You can also call core JavaScript enclosing it within backticks (this is also undocumented). It's good for small blocks of code and for core functions:
length: unit(`Math.log(@{value})`, px);
If you run your Less processor from a Node.js app you can call your own functions that way.
Upvotes: 0
Reputation: 10440
You can't define variables dynamically in LESS right now, but you can dynamically define selectors (as you probably knew). I will just give an example of that and leave it to you to apply it to the color/variables issue.
.towerMaker (@index) when (@index > 0) {
.block-@{index} {
z-index: @{index};
}
.towerMaker(@index - 1);
}
.towerMaker (7);
Upvotes: 1