less Learning Notes 7 - Language Features (Loop&Merge&Parents Selectors)

Keywords: less Attribute

So far as this article is concerned, the language features of less documents have been completed. In the process of reading, it is still recommended to combine the original text of the official website to understand and install less in the computer. Follow the content and try it on your own. It will be more intuitive to see the compiled results, and more attempts can be made to deepen the understanding. The next part is Les's function manual, which will probably come out next week to try not to delay. It won't delay the results of last weekend as mentioned in two articles. It will write some down-to-earth every day.

Loop

In less, a mixin can call itself. When guards expressions and pattern matching are combined, such a recursive mixins can be used to create a variety of iteration / loop structures.

.loop(@counter) when (@counter > 0) {
  .loop((@counter - 1));    // Next iteration
  width: (10px * @counter); // Code for each iteration
}

div {
  .loop(5); //Starting cycle
}

//Compile to:

div {
  width: 10px;
  width: 20px;
  width: 30px;
  width: 40px;
  width: 50px;
}

A common example of using recursive loops is generating grid classes for CSS:

.generate-columns(4);

.generate-columns(@n, @i: 1) when (@i =< @n) {
  .column-@{i} {
    width: (@i * 100% / @n);
  }
  .generate-columns(@n, (@i + 1));
}

//Compile to:

.column-1 {
  width: 25%;
}
.column-2 {
  width: 50%;
}
.column-3 {
  width: 75%;
}
.column-4 {
  width: 100%;
}

Merge

Merge attribute

The merge feature allows the values of multiple attributes to be aggregated into a single attribute list separated by commas or spaces. Merge is very useful for properties like background and transform.

comma

Published in v1.5.0

.mixin() {
  box-shadow+: inset 0 0 10px #555;
}
.myclass {
  .mixin();
  box-shadow+: 0 0 20px black;
}

//Compile to:

.myclass {
  box-shadow: inset 0 0 10px #555, 0 0 20px black;
}

Spaces

Published in v1.7.0

.mixin() {
  transform+_: scale(2);
}
.myclass {
  .mixin();
  transform+_: rotate(15deg);
}

//Compile to:

.myclass {
  transform: scale(2) rotate(15deg);
}

To avoid various unintentional connections, merge requires a clear "+" or "+" tag in each declaration that requires connections.

parent selectors

Operators represent parent selectors in nesting and are often used when adding a modified class or pseudoclass to an existing selector.

a {
  color: blue;
  &:hover {
    color: green;
  }
}

//Compile to:

a {
  color: blue;
}

a:hover {
  color: green;
}

Notice that if there is no & the above ex amp le will not produce a:hover style (it will become a descendant selector that matches any hovering element in the < a > tag), which is not what we want to nest: hover's pseudo class selector.
The parent selector operator has a variety of uses, and you can combine nested rule selectors in other ways that are not default. Another typical use is to produce duplicate class names:

.button {
  &-ok {
    background-image: url("ok.png");
  }
  &-cancel {
    background-image: url("cancel.png");
  }

  &-custom {
    background-image: url("custom.png");
  }
}

//Compile to:

.button-ok {
  background-image: url("ok.png");
}
.button-cancel {
  background-image: url("cancel.png");
}
.button-custom {
  background-image: url("custom.png");
}

Multiple &

Multiple occurrences in a selector make it possible to refer to the parent selector repeatedly without repeating its name.

.link {
  & + & {
    color: red;
  }

  & & {
    color: green;
  }

  && {
    color: blue;
  }

  &, &ish {
    color: cyan;
  }
}

//Compile to:

.link + .link {
  color: red;
}
.link .link {
  color: green;
}
.link.link {
  color: blue;
}
.link, .linkish {
  color: cyan;
}

Note that & represents all parent selectors (not the most recent parent selector):

.grand {
  .parent {
    & > & {
      color: red;
    }

    & & {
      color: green;
    }

    && {
      color: blue;
    }

    &, &ish {
      color: cyan;
    }
  }
}

//Compile to:

.grand .parent > .grand .parent {
  color: red;
}
.grand .parent .grand .parent {
  color: green;
}
.grand .parent.grand .parent {
  color: blue;
}
.grand .parent,
.grand .parentish {
  color: cyan;
}

Change the order of selectors

This allows the current selector to take precedence over its parent selector, which can be achieved by placing & behind the current selector. When using Modernize, you may want to specify different rules based on the supported features:

.header {
  .menu {
    border-radius: 5px;
    .no-borderradius & {
      background-image: url('images/button-background.png');
    }
  }
}

The'.no-borderradius &'selector will give'.no-borderradius' selector priority over its parent selector'.header.menu'. This compiles to ".no-borderradius.header.menu"

.header .menu {
  border-radius: 5px;
}
.no-borderradius .header .menu {
  background-image: url('images/button-background.png');
}

Combinatorial Explosion

You can produce all possible selector arrays in a comma-separated list.

p, a, ul, li {
  border-top: 2px dotted #366;
  & + & {
    border-top: 0;
  }
}

//This results in all possible combinations of specified elements:

p,
a,
ul,
li {
  border-top: 2px dotted #366;
}
p + p,
p + a,
p + ul,
p + li,
a + p,
a + a,
a + ul,
a + li,
ul + p,
ul + a,
ul + ul,
ul + li,
li + p,
li + a,
li + ul,
li + li {
  border-top: 0;
}

Posted by PABobo on Fri, 11 Jan 2019 00:03:10 -0800