1

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;}
Richard Parnaby-King
  • 14,703
  • 11
  • 69
  • 129
  • Yes, variables can be used to generate class names like `.@{var}{...}` (selector interpolation). But for your case, I think you also need a loop to create one class for each color. – Harry Sep 01 '14 at 10:20
  • How would that be done? – Richard Parnaby-King Sep 01 '14 at 10:29
  • A very basic example would be like [this](http://codepen.io/hari_shanx/pen/kEzws). – Harry Sep 01 '14 at 10:34
  • I can see it working in codepen (and I love it), however it is not compiling for me. I am using the PHP Less compiler - lessphp v0.4.0 http://leafo.net/lessphp. – Richard Parnaby-King Sep 01 '14 at 10:48
  • Less PHP is not quite updated with the new features and the reason could be the same as the one mentioned in [this](http://stackoverflow.com/questions/24757612/simplifying-repetitive-less/24758422#24758422) thread. – Harry Sep 01 '14 at 10:52
  • Excellent :) Could you post this as an answer please? – Richard Parnaby-King Sep 01 '14 at 10:57

1 Answers1

2

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.

Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214
  • 1
    I have variables for my colours, so I changed `background:@color;` to `background:@@color;`. LESS PHP (apparently) does not support length, so I had to change the value the number of elements in @colours: `.loop-colors(5);` – Richard Parnaby-King Sep 01 '14 at 11:18