Dynamic Variable Names in LESS CSS
You can use Variable Names. And I've tested the code at http://lesstester.com/, it works.
@horizontal-default-color: #fff;
@horizontal-inverse-color: #000;
.horizontal-variant(@variant) {
@color: "horizontal-@{variant}-color";
color: @@color;
}
.horizontal-default{
.horizontal-variant(default);
}
.horizontal-inverse{
.horizontal-variant(inverse);
}
Dynamically define a variable in LESS CSS
This Cannot Be Done
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:
Idea #1 (Variable Variables)
.define(@var) {
@fooBar: 0;
@fooTwo: 2;
@fooYep: 4;
@fooSet: 'foo@{var}';
}
.define(Two);
.test {
.define(Bar);
prop: @@fooSet;
}
.test2 {
prop: @@fooSet;
}
Idea #2 (Parametric Mixins)
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;
}
CSS Output (for both ideas)
.test {
prop: 0;
}
.test2 {
prop: 2;
}
Conclusion
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.
Dynamic Variable Names with Less
use:
@cyan: "cyan-@{palette}";
p{
color: @@cyan;
}
or
@whitename: "white-@{palette}";
@white: @@whitename;
p{
color: @white;
}
Resolving dynamic variables in LESS
Missing Brackets
You are missing a set of needed brackets to resolve the variable:
LESS
//imported from another file
@button-primary: cyan;
@button-success: green;
@button-info: orange;
@button-warning: yellow;
@button-danger: red;
//in your mixin file
.loop-class(~"primary", ~"success", ~"info", ~"warning", ~"danger";);
.loop-class(@list, @index: 1) when (isstring(extract(@list, @index))) {
@status: extract(@list, @index);
.button-@{status} {
color: ~'@{button-@{status}}'; /* two more brackets needed */
| |
here here
}
.loop-class(@list, (@index + 1));
}
CSS Output
.button-primary {
color: #00ffff;
}
.button-success {
color: #008000;
}
.button-info {
color: #ffa500;
}
.button-warning {
color: #ffff00;
}
.button-danger {
color: #ff0000;
}
Cleaner More Friendly Code
Also, as a matter of less cluttered and more user friendly code, you can remove your multiple string interpolations needed for the mixing call by changing isstring
to iskeyword
in your mixin:
.loop-class(primary, success, info, warning, danger;); /* cleaner code on call */
.loop-class(@list, @index: 1) when (iskeyword(extract(@list, @index))) {
@status: extract(@list, @index);
.button-@{status} {
color: ~'@{button-@{status}}';
}
.loop-class(@list, (@index + 1));
}
less css calling dynamic variables from a loop
I have just been trying todo the same thing today with LESS. The solution I came up with is to use a Parametric Mixin to create (define) the variable, see updated exmaple:
@color1:#06A1C0;
@color2:#8F4F9F;
@color3:#ED1D24;
@color4:#5A9283;
@color5:#B38C51;
@color6:#EC008C;
@color7:#8F4F9F;
@iterations: 7;
.define(@var) {
@colorSet: 'color@{var}';
}
.mixin-loop (@index) when (@index > 0) {
color@{index}:hover{
.define(@index);
color: @@colorSet;
}
.mixin-loop(@index - 1);
}
.mixin-loop (0) {}
.mixin-loop(@iterations);
Hope this helps.
How have dynamic class names in LESS CSS and use them as values in function
You have to create a list of colors first before creating a loop:
.make-classes(@prefix, @list) {
.iter(length(@list));
.iter(@i) when (@i > 0) {
.iter(@i - 1);
@pair: extract(@list, @i);
@key: extract(@pair, 1);
@value: extract(@pair, 2);
.@{prefix}.color-@{key} {
color: @value;
}
}
}
@colors:
~'blue' #7FB3D4,
~'gray' #767676,
~'green' #8CC079,
~'red' #b35d5d;
.make-classes(link, @colors);
Output:
.link.color-blue {
color: #7fb3d4;
}
.link.color-gray {
color: #767676;
}
.link.color-green {
color: #8cc079;
}
.link.color-red {
color: #b35d5d;
}
Pass dynamic variable from HTML to less.css file
I would recommend you to do something like the following:
- Give the user a pre-defined list of theme colors to choose from (a drop-down maybe). Don't allow for entering any color they wish to, that would be a pain.
- When the select any color append, the color name to the
body
as aclass
using jQuery/JS. In Less, write the below code, compile it statically and link the compiled CSS to your page.
body {
background-color: red; /* default */
&.red {background-color: red;}
&.green{background-color: green;}
&.blue{background-color: blue;}
}
window.onload = function() {
document.querySelector('#color-chooser').addEventListener('change', function() {
document.body.className = this.value;
});
}
/* compiled CSS based on the Less code provided above */
body {
background-color: red;
/* default */
}
body.red {
background-color: red;
}
body.green {
background-color: green;
}
body.blue {
background-color: blue;
}
<label>Select Background Color:</label>
<select id='color-chooser'>
<option value='red'>Red</option>
<option value='blue'>Blue</option>
<option value='green'>Green (Hex)</option>
</select>
Related Topics
Make Text in Select Element Wrap When Too Long
Clamping Lines Without '-Webkit-Line-Clamp'
Bootstrap Change Carousel Height
Svg + CSS3 Animation Not Working with Link Markup
Do Ie Browsers (IE6, 7, 8) Support @Font-Face
Css, Change Less Variable with @Media
CSS Hover Menu Appearing Behind PDF Iframe
CSS Property Box-Reflect Compatibility
Using Undefined Number of Arguments in Mixins
Should I Avoid Using "Text-Align: Justify;"
How to Make a Link Inside a Div Fill the Entire Space Inside the Div
How to Set Keyframes Name in Less
Nginx Failing to Load CSS and Js Files (Mime Type Error)
Media Queries for Tablet Min-Resolution and Max-Resolution
Applying Webkit Transitions to Pseudo Elements
Disable Bootstrap for One Element