LESS Declare variables using class names?

2019-03-02 10:28发布

问题:

I have a button class that sets up padding etc for an element, followed by a class that defines a background colour.

.button {
    padding: 0.5em 1em;
    text-transform: uppercase;
    color: #fff;
    &.green {
        background:@green; //declared previously
    }
    // ... more colours
}

Is it possible to declare the @green variable as the class name? This would save me having to copy/paste the &.green block for each colour I am wanting to use.

I've not been able to find anything the docs regarding this sort of selector, but something along the lines of:

&.(green|blue|red) {
    background: @{$1};
}

which would generate the following:

.button.green{background:#00ff00;}
.button.blue{background:#0000ff;}
.button.red{background:#ff0000;}

回答1:

You could achieve this by having a variable with the required list of colors, a loop to create the required rules and selector interpolation like shown below.

@colors: "green","blue","orange","red","yellow"; // the list of colors required
button {
    padding: 0.5em 1em;
    text-transform: uppercase;
    .loop-colors(@index) when (@index > 0){ // loop to generate rules for each color
        .loop-colors(@index - 1); // call for the next iteration
        @color: e(extract(@colors, @index)); // pick the color value from the list one by one based on current index
        &.@{color} {
            background:@color;
        }
    }
    .loop-colors(length(@colors));
}

Codepen Demo

Note: As mentioned in comments, LESS PHP is quite outdated and hence some of the new features offered by LESS (with respect to loops) are not supported by it. It could be overcome by doing the work-around mentioned in this answer.

You could also adopt an approach similar to the one mentioned by seven-phases-max in this answer (2nd option). That one achieves a similar effect without using loops.