1

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:

  • .default( gives the default style )
  • {.colours} (so that the background, the border and all colour related properties are setted)
  • {.icon-after or .icon-before} so that I can choose if adding the icon before or after with the proper margin
  • {.icon-name} (for example a questionmark or a tick etc)

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.

Huangism
  • 16,278
  • 7
  • 48
  • 74
Nick
  • 13,493
  • 8
  • 51
  • 98
  • 3
    I'm not sure I understand what doesn't work? By the way you've written your LESS file it's possible to set this on an element: `class="default red icon-after"`. Why not? – Robert Koritnik Sep 15 '14 at 15:51
  • Yeah I know, I will edit the question and explain it better. – Nick Sep 15 '14 at 15:53
  • Why do you want this? What's undesirable about your current output? – Eric Sep 15 '14 at 15:53
  • This would of been much easier if you posted the css code that you wanted to convert to LESS – Huangism Sep 15 '14 at 16:09
  • 1
    You could simplify this a lot by making use of loops like [here](http://codepen.io/hari_shanx/pen/wjIpn). There is a lot of repetitive code in there. Also, check if the structure in that sample meets your needs. – Harry Sep 15 '14 at 16:11
  • @Harry your code seams to be a bit complex, do you mind explain it? Sorry but this is my first project using less and i'm not good yet – Nick Sep 15 '14 at 16:17
  • I can definitely explain mate, but comments would be too small an area. If that is what you are intending to do then I would add a detailed answer with an explanation. – Harry Sep 15 '14 at 16:17
  • 1
    I would suggest `extend` but actualy I can't see why you need to put `.icon-after`/`.icon-before` after colors at all. Note that `.default.icon-after` selector will match `` just fine. – seven-phases-max Sep 15 '14 at 16:18
  • I think so, I'm playing with it and I think is what i really need, whit a better optimization as well. – Nick Sep 15 '14 at 16:19
  • 1
    [This answer](http://stackoverflow.com/questions/25603517/less-declare-variables-using-class-names/25604556#25604556) has a bit of explanation on something similar with loops. I have also added some comments to explain the code in that demo that I gave above. And seven-phases-max definitely has a point in his comment. – Harry Sep 15 '14 at 16:21
  • @user3760661: Did that help? Are you comfortable with me making that as an answer? – Harry Sep 15 '14 at 16:36
  • @Harry yes. With your example and the answer you mentioned I was able to do it. Thanks a lot. Make it in a question so that I can choose you ;) – Nick Sep 16 '14 at 07:04

2 Answers2

2

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:

  1. @colors - An array list variable which has the list of colors required for the element.
  2. @bckground - Another array list variable which holds the required background color for each color class declared in the @colors list.
  3. 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.
  4. &.@{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.
  5. 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).

Harry
  • 87,580
  • 25
  • 202
  • 214
  • I've another question, I wrote it here: http://stackoverflow.com/questions/25863565/less-loops-set-result-as-after-and-before-content If you'd like to help even for this would be great. Cheers – Nick Sep 16 '14 at 08:08
0
.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{
          [...]
          }
     }
}
ersoma
  • 1
  • 1
  • I can't do like this, as all the colours are different – Nick Sep 15 '14 at 15:57
  • Then insert .icon-before{[...]} to every color: &.black { background: @blackBackground; border: @blackBorder; color: @lightText; text-shadow: @blackTextShadow; &:hover { background: darken(@blackBackground, 10%); } .icon-before{[...]} } – ersoma Sep 15 '14 at 15:59
  • There's not a quicker way to do it? Cause I will be able to add colours and icon without having to add every time a new class and icon into every colour – Nick Sep 15 '14 at 16:01
  • Do you mean something like this? [link](http://lesscss.org/features/#extend-feature) – ersoma Sep 15 '14 at 16:06
  • @ersoma you can edit your answer instead of posting new code to comments – Huangism Sep 15 '14 at 16:07