Dynamic Variable Names in Less CSS

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 a class 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



Leave a reply



Submit