4

After reading tutorial after tutorial regarding Less (LessCSS), I was just wondering how this & operator is supposed to be used. I know it's referring the parent element like:

div {
  &.fullheight {
    height: 100%;
  }
}

// turns into

div.fullheight {
  height: 100%;
}

But I often saw this:

div {
    span {
        & {
          padding: 1em;
          margin: 1em;
        }
    }
}

// turns into

div span {
  padding: 1em;
  margin: 1em;
}

Like when using ONLY the & operator inside of a class, it represents pretty much the parent element, but is doing this bad practise since you can have the same result when you would type like this:

div {
    span {
      padding: 1em;
      margin: 1em;
    }
}

Both work, so is it bad/good practise or are each of them maybe used in different situations?


For extra clarity, below is the link to an answer where I first saw that you can write & only in a class without anything else.

LESSCSS - use calculation and return value - First post by ScottS, fourth solution in his post.

Community
  • 1
  • 1
denii
  • 99
  • 5
  • The `&` there is just redundant for this case and so I'd say it is bad practice to write like that. If you can post the actual code where you saw such a nested block (with only `&` as selector) then maybe we can comment more. – Harry Jun 15 '16 at 03:53
  • http://stackoverflow.com/questions/22794231/lesscss-use-calculation-and-return-value - First post by ScottS, fourth solution in his post. There I first saw that you can write & only in a class without anything else. – denii Jun 15 '16 at 04:19
  • 1
    I've edited the title a bit because generally questions that ask *is this good/bad practice* look like they are asking for opinions and get closed. If you don't agree with my edit, please feel free to roll it back. – Harry Jun 15 '16 at 05:12

1 Answers1

4

Generally writing something like below would be considered as bad practice because the & there is just redundant and does no value add at all. It just outputs the entire parent selector div span.

div {
  span {
    & {
      padding: 1em;
      margin: 1em;
    }
  }
}

So, you should avoid writing such selectors which use only the & (parent selector).


The other example to which you have linked is an interesting case which I would term as an educated hack to get around the variable scoping and lazy loading concepts in Less.

Assume that the same code was written without the parent selectors (like below).

@unit:em;
@basevalue:1;
@val: 1;
@setUnit: unit(@basevalue*@val, @unit);

.someAwesomeClass { 
  @val: .2; 
  padding: @setUnit;
  @val: .1; 
  margin: @setUnit;
}

Here the @val variable is declared twice within the same block. Since Less does lazy loading of the variables, they need not be declared before being used (and) if the same variable is declared twice or more within the same scope, the last declaration would win.

When defining a variable twice, the last definition of the variable is used, searching from the current scope upwards. This is similar to CSS itself where the last property inside a definition is used to determine the value.

So, the compiled CSS output would have the value as 0.1em for both padding and margin whereas the expectation is for padding to be 0.2em and for margin to be 0.1em.

To overcome this, the author of that answer has introduced two namespaces (with no name) and has thus restricted the scoping issue. The variable defined within each nested block becomes local to that block only and so will be considered as two separate variables.

@unit:em;
@basevalue:1;
@val: 1;
@setUnit: unit(@basevalue*@val, @unit);

.someAwesomeClass { 
  &{
    @val: .2; /* this declaration applies only within this nest */
    padding: @setUnit;
  }
  &{
    @val: .1; /* this declaration applies only within this nest */
    margin: @setUnit;
  }
}

As indicated by the author of that answer (in the first line), it was a workaround because there was no way to create a true function with Less.

But starting with Less v2, we can define our own custom functions in Less and use them as described in this answer by Bass Jobsen. The ability to write such custom functions should eliminate the need to write such hacks.

You can also refer to the comment by seven-phases-max in the same thread for a solution without the need for such hacks.


Bottomline is that usage of & alone as a selector is a bad practice. The solution in the linked answer was a hack which was useful in earlier versions of Less. It is still useful but there are alternate options and so & alone as a selector should be used only in extremely rare circumstances where none of the other option work.

Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214
  • Alright, this literally made things much clearer for me, thank you very much for your long and advanced answer. But since I started with less yesterday - is there any null to perfect-writing beautiful less code guide/tutorial you would recommend? Thanks in advance. :) – denii Jun 15 '16 at 05:17
  • 1
    @denii: Actually no. The only reference I use for Less is the [official Less Website](http://lesscss.org/) because it is constantly evolving and so things described in unofficial tutorials may once have been very useful but now could either be completely wrong or outdated. – Harry Jun 15 '16 at 05:21