Reputation: 14283
I'm using LESS as css compiler.
Everything works fine, but now I need to create a specific class structure and I'm a bit stuck.
I'd like to have this structure:
.default .{color} {.icon-after/.icon-before} {.icon}
this is the code that I've done:
.default {
&.disabled {
background: lighten(@grayBackground, 5%);
color: lighten(@darkText, 35%);
cursor: default;
border: @grayBorder;
text-shadow: @grayTextShadow;
}
&.gray {
background: @grayBackground;
color: @darkText;
border: @grayBorder;
text-shadow: @grayTextShadow;
&:hover {
background: darken(@grayBackground, 5%);
}
}
&.green {
background: @greenBackground;
border: @greenBorder;
color: @lightText;
text-shadow: @greenTextShadow;
&:hover {
background: darken(@greenBackground, 10%);
}
}
&.yellow {
background: @yellowBackground;
border: @yellowBorder;
color: @lightText;
text-shadow: @yellowTextShadow;
&:hover {
background: darken(@yellowBackground, 10%);
}
}
&.blue {
background: @blueBackground;
border: @blueBorder;
color: @lightText;
text-shadow: @blueTextShadow;
&:hover {
background: darken(@blueBackground, 10%);
}
}
&.black {
background: @blackBackground;
border: @blackBorder;
color: @lightText;
text-shadow: @blackTextShadow;
&:hover {
background: darken(@blackBackground, 10%);
}
}
&.red {
background: @redBackground;
border: @redBorder;
color: @lightText;
text-shadow: @redTextShadow;
&:hover {
background: darken(@redBackground, 10%);
}
}
&.icon-before{
.IconDefaultStyleBefore
}
&.icon-after{
.IconDefaultStyleAfter()
}
}
obviously this doesn't work, as the result is something like this:
.default .{color / .icon-after / .icon-before}
Any suggestions on how can I obtain my structure?
Thanks a lot
EDIT
I'd like to add the classes to the buttons in this order:
so, for example, adding this classes:
.default .blue .icon-before .tick
I will have:
default blue button with the tick icon before the text
Hope is now more clear than before.
Upvotes: 1
Views: 134
Reputation: 89750
The required structure can be achieved as shown in the below example. The code can be simplified a lot by using loops (guarded mixins).
Explanation:
@colors
- An array list variable which has the list of colors required for the element.@bckground
- Another array list variable which holds the required background color for each color class declared in the @colors
list.e(extract(@colors, @index))
and extract(@bckground, @index)
- Extract functions are used to fetch the color name and background color value corresponding to the index of each array iteration (similar to colors[i]
). e()
function is used to extract the color values without the quotes. &.@{color}
- Selector interpolation to form the selector value. &
is the parent selector and @{color}
is the name of the color from the @colors
list variable.length(@colors)
- The no. of color items present in the @colors
array list variable. This is passed to the loop function to tell the Less Compiler as to how many times the loop should be executed.@colors: "red","green","black","blue","gray";
@bckground: #AAA, #0F0, #00F, #000, #F00;
.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));
@bgColor: extract(@bckground, @index);
&.@{color}{
background: @bgColor; //set background
/* all other props */
&:hover {
background: darken(@bgColor, 5%);
}
&.icon-before{
.IconDefaultStyleBefore;
}
&.icon-after{
.IconDefaultStyleAfter();
}
}
}
.default{
.loop-colors(length(@colors));
}
Note: As seven-phases-max mentioned in his comment, we are essentially generating a selector structure like .default.red.icon-before
. Such a selector would essentially mean the same element has all the three classes and so even if it is specified like .default.icon-before.red
it wouldn't make any difference but I assume that you are trying to make a more readable structure (like a default red button with an icon-before).
Upvotes: 2
Reputation: 1
.default{
[...]
&.gray, &.black, [...every color...] {
.icon-before{
[...]
}
}
}
EDIT: or if you need a different .icon-before for every color you have to insert it one by one:
.default{
[...]
&.gray{
[...]
.icon-before{
[...]
}
}
}
Upvotes: 0