11

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.

3
  • i would highly recommend taking a look at font-awesome's less-sheet ;-) Commented Nov 4, 2012 at 0:12
  • thanks - will look into it. Too deep into this current project to make such a big shift, however. Commented Nov 9, 2012 at 1:40
  • Just as an FYI - I spent enough time working with font-based icons now... I'm actually having to go back in and rip out all the image based stuff. The ability to mod color, text-shadow, size etc... makes font-based icons infinitely superior. Commented Jul 19, 2013 at 18:50

2 Answers 2

15

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;
}
Sign up to request clarification or add additional context in comments.

4 Comments

I get that this is the "correct" way of building mixins - but I'm trying to work backwards from an existing set of rules. I just want to apply these things piecemeal to an element.
AFAIK, it's impossible to use multiple-class rules (like .class1.class2) as mixins in LESS. So, from your set of selectors, only .icon can be used as a mixin.
I can't seem to find it now, but I ran across a thread that specifically said you could do multiclass rules like this... Anyone have a definitive answer on that?
Maybe you are talking about namespaced mixins (single class inside id as child selector): #some-namespace > .example-mixin.
4

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.

3 Comments

Huh. Will have to check this out straight away. It's rather alarming that different Less compilers act so differently. The compiler I'm using is a plugin for the Sublime text editor - which I haven't had any issues with (beyond this). I know there are a number of standalone compilers too... will have to do some testing I guess. Thanks for the help on this - I really dig Less, but was a bit frustrated to run into this issue.
I'm switching over to the standalone WinLess - which manages to compile these particular rules successfully. Cheers!
@Bosworth99--I'm glad for your purposes you could switch to a compiler that did what you needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.