Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LessCss : multiple class selectors with & keyword

Tags:

html

css

less

Say - have a .less sheet with a large number of "multiple" css rules to manage iconography. Something like so:

.icon { display:inline-block; position:relative; text-indent:-9999em;}
.icon-l.legend { width:24px; height:24px;}
.icon-white.legend{ background:url(@icon_legend_white) no-repeat;}
.icon-l.arrow_left{background-position: -128px -32px;}

and apply rules like this as such:

<i class="icon icon-l icon-color legend arrow_left"></i>

This works fine when I have access to markup, as one would expect, but I'm having a hard time applying these rules via less to a given element:

Here's what i would expect to work:

#something{
  .icon;
  .icon-l.legend;
  .icon-white.legend;
  .icon-l.arrow_left;
}

Which just throws an error.

I'm "led to believe" that the "&" operator can apply rules like so:

#something{
 .icon;
 .icon-l{&.legend{}};
 .icon-white{&.legend{}};
 .icon-l{&.arrow_left{}};
}

This throws no error, but only the rules for .icon are getting applied.

Anyone have a solution?

UPDATE

FYI - I'm compiling several .less files together for many different unique sheets. Works really well.

SublimeText2 plugin - works reasonably well, and integrates really well into the workflow (need to 'build' the file) - but could not render multiple classes like this

SimpLess - is a nice standalone that I like alot, except that I kept getting errors compiling my less stack - without clear reference to the error location

WinLess - manages to complete all my compiling needs, as well as successfully compiling multiple classes like this. Also - its error reporting is very specific. Making it the winner.

like image 981
Bosworth99 Avatar asked Nov 04 '12 00:11

Bosworth99


2 Answers

Mixin name should consist of a single class name, not multiple ones. Create a mixin like this:

.icon() {
    display: inline-block;
    position: relative;
    text-indent: -9999em;

    &.icon-l.legend {
        width: 24px;
        height: 24px;
    }

    &.icon-white.legend {
        background: url(@icon_legend_white) no-repeat;
    }

    &.icon-l.arrow_left {
        background-position: -128px -32px;
    }
}

and then use it this way:

#something {
    /* "Injecting" .icon mixin into #something */
    .icon;
}
like image 151
Marat Tanalin Avatar answered Sep 29 '22 18:09

Marat Tanalin


Appears to be a Compiler Issue

If you take your original idea of:

.icon { display:inline-block; position:relative; text-indent:-9999em;}
.icon-l.legend { width:24px; height:24px;}
.icon-white.legend{ background:url(@icon_legend_white) no-repeat;}
.icon-l.arrow_left{background-position: -128px -32px;}

With

#something{
  .icon;
  .icon-l.legend;
  .icon-white.legend;
  .icon-l.arrow_left;
}

Then assuming you assign something to the variable @icon_legend_white, then the online winless compiler compiles it to the following (where the variable was set to "somepath"):

#something {
  display: inline-block;
  position: relative;
  text-indent: -9999em;
  width: 24px;
  height: 24px;
  background: url("somepath") no-repeat;
  background-position: -128px -32px;
}

So if your compiler is throwing an error, then there is obviously some difference between how they are compiling. A solution would then be to switch compilers, or debug the one you are using.

Update

Some further experimenting with the winless compiler shows that it will only work if the items are defined by classes or ids (which is understandable, as that is what is stated as valid for mixins), but it does have a bug in that it will mixin either or both of .icon-l.legend and .icon-l .legend by a simple mixin call of either one. So the "space" between the second set (making it a child selector) is ignored if called as a mixin. That is certainly wrong for that compiler. Another online compiler does not seem to suffer from that bug, but still compiles according to your original attempt.

like image 38
ScottS Avatar answered Sep 29 '22 18:09

ScottS