Quickly get Less - the parent selector

1 Overview

Extend is a Less pseudo-class that extends the rules of the current hierarchy.

nav ul {
  &:extend(.inline);
  background: blue;
}

In the rule set above, :extendthe selector .inlinewill apply the rules of to the "extended selector" ie nav ul. At the same time, nav ulthe rules themselves will remain as they are.

As follows:

nav ul {
  &:extend(.inline);
  background: blue;
}
.inline {
  color: red;
}

The generated result is as follows:

nav ul {
    
    
  background: blue;
}
.inline,
nav ul {
    
    
  color: red;
}

2. Grammar

extendLooks like a pseudo-class that can be attached directly to a selector or used in a ruleset, and also supports an optional keyword all.
Examples are as follows:

// 方式 1:直接附加在选择器上
.a:extend(.b) {
  color: red;
}

// 方式 2:在规则集中使用
.a {
  &:extend(.b);
  color: red;
}

// 上面两种方式效果完全一致

allThe use of keywords

.c:extend(.d all) {
  // 扩展 `.d` 的所有相关选择器,例如 `.x.d` 或 `.d.x`
  color: red;
}
.c:extend(.d) {
  // 仅扩展选择器 `.d`
  color: red;
}

Of course, it can also contain one or more classes to be extended, separated by commas , examples are as follows:

.e:extend(.f) {
  color: red;
}
.e:extend(.g) {
  color: red;
}

// 和上面两个得到的结果完全一致
.e:extend(.f, .g) {
  color: red;
}

3. Attach to the selector

Extend attached to a selector looks like a normal pseudo-class with the selector as a parameter, while a selector can contain multiple extend clauses, but all extend must be at the end of the selector.

  • After the selector:pre:hover:extend(div pre)
  • There can be spaces between the selector and the extension:pre:hover :extend(div-pre)
  • Multiple extensions are allowed: pre:hover:extend(div pre):extend(.bucket tr), in fact, this has exactly the same pre:hover:extend(div pre, .bucket tr)effect
  • The extension must come last, so this is not allowed:pre:hover:extend(div pre).nth-child(odd)

If the ruleset contains multiple selectors, any of them can be extended, examples are as follows:

// 附加到选择器
.bag {
  border: 1px solid;
}

.bucket {
  margin: 10px;
}

.show {
  display: block;
}

.big-division:extend(.bag),
.big-bag:extend(.bag, .show),
.big-bucket:extend(.bucket):extend(.show) {
  color: red;
}

The generated result is as follows:

.bag,
.big-division,
.big-bag {
    
    
  border: 1px solid;
}
.bucket,
.big-bucket {
    
    
  margin: 10px;
}
.show,
.big-bag,
.big-bucket {
    
    
  display: block;
}
.big-division,
.big-bag,
.big-bucket {
    
    
  color: red;
}

4. Use in rule sets

In addition to being attached to the selector, it can also be used directly in the rule set. The parent selector is also supported, such as: , &:extend(selector)and after being placed in the rule set, all selectors corresponding to the rule set will be expanded (a shortcut Way).

.ru {
  top: 10;
}

pre:hover,
.some-class {
  &:extend(.ru);
  left: 20;
}

// 和上面写法完全一致
pre:hover:extend(.ru),
.some-class:extend(.ru) {
  left: 20;
}

The generated result is as follows:

.ru,
pre:hover,
.some-class {
    
    
  top: 10;
}
pre:hover,
.some-class {
    
    
  left: 20;
}

5. Expand nested selectors

Extend can match nested selectors. The following less:

.bucket {
  tr { // 嵌套的选择器
    color: blue;
  }
}
.some-class:extend(.bucket tr) {
  border: 1px;
}

The generated result is as follows:

.bucket tr,
.some-class {
    
    
  color: blue;
}
.some-class {
    
    
  border: 1px;
}

Also, the extension ends up using css instead of the original less.

.bucket {
  tr & {
    color: blue;
  }
}
.some-class:extend(tr .bucket) {
  border: 1px;
}

The generated result is as follows:

tr .bucket,
.some-class {
    
    
  color: blue;
}
.some-class {
    
    
  border: 1px;
}

6. Exact match

By default, :extend(selector)the selector will be matched exactly, that is, it needs to be exactly the same to match.

.a.class,
.class.a,
.class > .a {
  color: blue;
}
.test {
  border: 1px;
}

Although in the selector, *.classand are .classequal , extendwill not match:

*.class {
  color: blue;
}

// 匹配不到任何选择器
.noStar:extend(.class) {
  border: 1px;
} 

The order of the pseudo-classes is also important. The selectors link:hover:visitedand link:visited:hoverdo match the same set of elements, but extendwill not match:

link:hover:visited {
  color: blue;
}

// 匹配不到任何选择器
.selector:extend(link:visited:hover) {
  border: 1px;
}

7. nthExpression

In selectors, the expressions 1n+3and n+3are equivalent, extendbut will not match them:

:nth-child(1n+3) {
  color: blue;
}

// 匹配不到任何选择器
.child:extend(:nth-child(n+3)) {}

8. Attribute Selector

Interestingly, the type of quotes in the attribute selector is irrelevant

[title='identifier'] {
  color: blue;
}
[title='identifier'] {
  color: blue;
}
[title='identifier'] {
  color: blue;
}

.noQuote:extend([title='identifier']) {
  border: 1px;
}
.singleQuote:extend([title='identifier']) {
  border: 1px;
}
.doubleQuote:extend([title='identifier']) {
  border: 1px;
}

The generated result is as follows:

[title='identifier'],
.noQuote,
.singleQuote,
.doubleQuote {
    
    
  color: blue;
}
[title='identifier'],
.noQuote,
.singleQuote,
.doubleQuote {
    
    
  color: blue;
}
[title='identifier'],
.noQuote,
.singleQuote,
.doubleQuote {
    
    
  color: blue;
}
.noQuote {
    
    
  border: 1px;
}
.singleQuote {
    
    
  border: 1px;
}
.doubleQuote {
    
    
  border: 1px;
}

9. allKeywords

When specifying allthe keyword , it tells Less to match that selector as part of another selector. Matched parts are replaced to generate a new selector. Examples are as follows:

a.b.test,
.test.c {
  color: orange;
}
.test {
  &:hover {
    color: green;
  }
}

.replacement:extend(.test all) {
  border: 1px;
}

The generated result is as follows:

a.b.test,
.test.c,
a.b.replacement,
.replacement.c {
    
    
  color: orange;
}
.test:hover,
.replacement:hover {
    
    
  color: green;
}
.replacement {
    
    
  border: 1px;
}

10. Variables

extendWill not match any variable, if the selector contains a variable, it will be ignored directly.

@variable: .bucket;
@{variable} {
  color: blue;
}
// 匹配不到任何选择器
.some-class:extend(.bucket) {
  border: 1px;
}
.bucket {
  color: blue;
}

@variable: .bucket;
// 匹配不到任何选择器
.some-class:extend(@{variable}) {
  border: 1px;
}

The official website points out: When the selector uses variables, it can be matched normally. But after I experimented, I found that it was impossible, and I left it for further study here.

11. @mediaUse in:extend

@mediaThe in matches :extendonly @mediathe selectors in the current .

@media print {
  // 成功匹配
  .screenClass:extend(.selector) {
    left: 1;
  } 
  // 同一个 media 中的选择器,匹配
  .selector {
    color: black;
  }
}
// 规则集在顶层,内层 extend 会忽略
.selector {
  color: red;
}

@media screen {
  // 规则集在另一 media 中,仅会被当前 media 中的 extend 匹配
  .selector {
    color: blue;
  }
}

The generated result is as follows:

@media print {
    
    
  .screenClass {
    
    
    left: 1;
  }
  .selector,
  .screenClass {
    
    
    color: black;
  }
}
.selector {
    
    
  color: red;
}
@media screen {
    
    
  .selector {
    
    
    color: blue;
  }
}

Note that selectors within nested @mediawithin the same will also not match@media

@media screen {
  // 匹配不到任何选择器
  .screenClass:extend(.selector) {
    left: 1;
  }
  @media (min-width: 1023px) {
    // 选择器在嵌套的 media 中,无法匹配
    .selector {  
      color: blue;
    }
  }
}

The top-level extend will match all levels of selectors

@media screen {
  .selector-t {
    color: blue;
  }
  @media (min-width: 1023px) {
    .selector-t {
      color: blue;
    }
  }
}

// 顶层的 extend 会去匹配所有层级的选择器
.topLevel:extend(.selector-t) {
  left: 1;
}

The generated result is as follows:

@media screen {
    
    
  .selector-t,
  .topLevel {
    
    
    color: blue;
  }
}
@media screen and (min-width: 1023px) {
    
    
  .selector-t,
  .topLevel {
    
    
    color: blue;
  }
}
.topLevel {
    
    
  left: 1;
}

12. Duplicate detection

Currently no duplicate detection is done as follows:

.alert-info,
.widget {
  left: 1;
}

.alert:extend(.alert-info, .widget) {
  top: 2;
}

The generated result is as follows:

.alert-info,
.widget,
.alert,
.alert {
    
    
  left: 1;
}
.alert {
    
    
  top: 2;
}

13. Example of use

13.1 Classic use cases

A typical use case is to avoid duplication of rulesets.

for example:

.animal {
  background-color: black;
  color: white;
}

If you want to override the background color animalof , there are two ways:

The first one: change the HTML and write two classes

<a class="animal bear"></a>
.animal {
  background-color: black;
  color: white;
}
.bear {
  background-color: brown;
}

The second: use extend

<a class="bear"></a>
.animal {
  background-color: black;
  color: white;
}
.bear {
  &:extend(.animal);
  background-color: brown;
}

13.2 Reduce CSS size

Using mixins is very convenient, but mixins will copy all the properties into the selector, which may cause unnecessary duplication.

Therefore, you can use extendsto replace the mixin to move the selector to the property you want to use, thereby reducing the generated CSS.

Let's see an example comparison:

  1. use mixins
.my-inline-block() {
  display: inline-block;
  font-size: 0;
}
.thing1 {
  .my-inline-block;
}
.thing2 {
  .my-inline-block;
}

The generated result is as follows:

.thing1 {
    
    
  display: inline-block;
  font-size: 0;
}
.thing2 {
    
    
  display: inline-block;
  font-size: 0;
}
  1. use extends
.my-inline-block {
  display: inline-block;
  font-size: 0;
}
.thing1 {
  &:extend(.my-inline-block);
}
.thing2 {
  &:extend(.my-inline-block);
}

The generated result is as follows:

.my-inline-block,
.thing1,
.thing2 {
    
    
  display: inline-block;
  font-size: 0;
}

13.3 Style composition

A more advanced usage is when the selector is more complex (mixin can no longer be implemented at this time, because mixin can only be used with simple selectors), and the rule set needs to be reused, then it can be used extends.

li.list > a {
  line-height: 20px;
}
button.list-style {
  &:extend(li.list > a);
}

The generated result is as follows:

li.list > a,
button.list-style {
    
    
  line-height: 20px;
}

Guess you like

Origin blog.csdn.net/qq_41800366/article/details/127284139