Extend 是一个 Less 伪类,它将它所放置的选择器与与其引用的匹配的选择器合并。
¥Extend is a Less pseudo-class which merges the selector it is put on with ones that match what it references.
发布于 v1.4.0
¥Released v1.4.0
nav ul {
&:extend(.inline);
background: blue;
}
在上面的规则集中,:extend
选择器会将 "继承选择器" (nav ul
) 应用于 .inline
类,无论 .inline
类出现在哪里。声明块将保持原样,但不会引用扩展(因为扩展不是 css)。
¥In the rule set above, the :extend
selector will apply the "extending selector" (nav ul
) onto the .inline
class wherever the .inline
class appears. The declaration block will be kept as-is, but without any reference to the extend (because extend isn't css).
所以如下:
¥So the following:
nav ul {
&:extend(.inline);
background: blue;
}
.inline {
color: red;
}
输出
¥Outputs
nav ul {
background: blue;
}
.inline,
nav ul {
color: red;
}
注意 nav ul:extend(.inline)
选择器如何获得 nav ul
的输出 - 扩展在输出之前被删除,选择器块保持原样。如果该块中没有放置任何属性,那么它将从输出中删除(但扩展仍然可能影响其他选择器)。
¥Notice how the nav ul:extend(.inline)
selector gets output as nav ul
- the extend gets removed before output and the selector block left as-is. If no properties are put in that block then it gets removed from the output (but the extend still may affect other selectors).
继承语法
¥Extend Syntax
扩展要么附加到选择器,要么放入规则集中。它看起来像一个带有选择器参数的伪类,可选地后跟关键字 all
:
¥The extend is either attached to a selector or placed into a ruleset. It looks like a pseudo-class with selector parameter optionally followed by the keyword all
:
示例:
¥Example:
.a:extend(.b) {}
.a {
&:extend(.b);
}
.c:extend(.d all) {
}
.c:extend(.d) {
}
它可以包含一个或多个要扩展的类,以逗号分隔。
¥It can contain one or more classes to extend, separated by commas.
示例:
¥Example:
.e:extend(.f) {}
.e:extend(.g) {}
.e:extend(.f, .g) {}
继承附加到选择器
¥Extend Attached to Selector
附加到选择器的扩展看起来像一个普通的伪类,将选择器作为参数。一个选择器可以包含多个扩展子句,但所有扩展都必须位于选择器的末尾。
¥Extend attached to a selector looks like an ordinary pseudo-class with selector as a parameter. A selector can contain multiple extend clauses, but all extends must be at the end of the selector.
在选择器之后扩展:pre:hover:extend(div pre)
。
¥Extend after the selector: pre:hover:extend(div pre)
.
选择器和扩展之间的空间是允许的:pre:hover :extend(div pre)
。
¥Space between selector and extend is allowed: pre:hover :extend(div pre)
.
允许多个扩展:pre:hover:extend(div pre):extend(.bucket tr)
- 注意这与 pre:hover:extend(div pre, .bucket tr)
相同
¥Multiple extends are allowed: pre:hover:extend(div pre):extend(.bucket tr)
- Note this is the same as pre:hover:extend(div pre, .bucket tr)
这是不允许的:pre:hover:extend(div pre).nth-child(odd)
。扩展必须在最后。
¥This is NOT allowed: pre:hover:extend(div pre).nth-child(odd)
. Extend must be last.
如果规则集包含多个选择器,则其中任何一个都可以具有 extend 关键字。在一个规则集中扩展的多个选择器:
¥If a ruleset contains multiple selectors, any of them can have the extend keyword. Multiple selectors with extend in one ruleset:
.big-division,
.big-bag:extend(.bag),
.big-bucket:extend(.bucket) {
}
继承内部规则集
¥Extend Inside Ruleset
可以使用 &:extend(selector)
语法将 Extend 放入规则集的主体中。将 extend 放入主体是将其放入该规则集的每个选择器的快捷方式。
¥Extend can be placed into a ruleset's body using &:extend(selector)
syntax. Placing extend into a body is a shortcut for placing it into every single selector of that ruleset.
在主体内继承:
¥Extend inside a body:
pre:hover,
.some-class {
&:extend(div pre);
}
与在每个选择器之后添加扩展完全相同:
¥is exactly the same as adding an extend after each selector:
pre:hover:extend(div pre),
.some-class:extend(div pre) {}
继承嵌套选择器
¥Extending Nested Selectors
Extend 能够匹配嵌套的选择器。关注 less:
¥Extend is able to match nested selectors. Following less:
示例:
¥Example:
.bucket {
tr {
color: blue;
}
}
.some-class:extend(.bucket tr) {}
输出
¥Outputs
.bucket tr,
.some-class {
color: blue;
}
本质上,extend 着眼于编译后的 css,而不是原始的 less。
¥Essentially the extend looks at the compiled css, not the original less.
示例:
¥Example:
.bucket {
tr & {
color: blue;
}
}
.some-class:extend(tr .bucket) {}
输出
¥Outputs
tr .bucket,
.some-class {
color: blue;
}
精确匹配继承
¥Exact Matching with Extend
默认情况下扩展会查找选择器之间的精确匹配。选择器是否使用前导星并不重要。两个第 n 个表达式具有相同的含义并不重要,它们需要具有相同的形式才能匹配。唯一的例外是属性选择器中的引号,less 知道它们具有相同的含义并匹配它们。
¥Extend by default looks for exact match between selectors. It does matter whether selector uses leading star or not. It does not matter that two nth-expressions have the same meaning, they need to have to same form in order to be matched. The only exception are quotes in attribute selector, less knows they have the same meaning and matches them.
示例:
¥Example:
.a.class,
.class.a,
.class > .a {
color: blue;
}
.test:extend(.class) {}
明星确实很重要。选择器 *.class
和 .class
是等价的,但 extend 不会匹配它们:
¥Leading star does matter. Selectors *.class
and .class
are equivalent, but extend will not match them:
*.class {
color: blue;
}
.noStar:extend(.class) {}
输出
¥Outputs
*.class {
color: blue;
}
伪类的顺序确实很重要。选择器 link:hover:visited
和 link:visited:hover
匹配同一组元素,但 extend 将它们视为不同的:
¥Order of pseudo-classes does matter. Selectors link:hover:visited
and link:visited:hover
match the same set of elements, but extend treats them as different:
link:hover:visited {
color: blue;
}
.selector:extend(link:visited:hover) {}
输出
¥Outputs
link:hover:visited {
color: blue;
}
第 n 个表达式
¥nth Expression
第 N 种表达形式很重要。第 N 个表达式 1n+3
和 n+3
是等价的,但扩展不会匹配它们:
¥Nth expression form does matter. Nth-expressions 1n+3
and n+3
are equivalent, but extend will not match them:
:nth-child(1n+3) {
color: blue;
}
.child:extend(:nth-child(n+3)) {}
输出
¥Outputs
:nth-child(1n+3) {
color: blue;
}
属性选择器中的引用类型无关紧要。以下所有内容都是等价的。
¥Quote type in attribute selector does not matter. All of the following are equivalent.
[title=identifier] {
color: blue;
}
[title='identifier'] {
color: blue;
}
[title="identifier"] {
color: blue;
}
.noQuote:extend([title=identifier]) {}
.singleQuote:extend([title='identifier']) {}
.doubleQuote:extend([title="identifier"]) {}
输出
¥Outputs
[title=identifier],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
[title='identifier'],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
[title="identifier"],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
继承 "all"
¥Extend "all"
当你在扩展参数中最后指定 all 关键字时,它会告诉 Less 将该选择器作为另一个选择器的一部分进行匹配。选择器将被复制,然后选择器的匹配部分将被扩展替换,从而形成一个新的选择器。
¥When you specify the all keyword last in an extend argument it tells Less to match that selector as part of another selector. The selector will be copied and the matched part of the selector only will then be replaced with the extend, making a new selector.
示例:
¥Example:
.a.b.test,
.test.c {
color: orange;
}
.test {
&:hover {
color: green;
}
}
.replacement:extend(.test all) {}
输出
¥Outputs
.a.b.test,
.test.c,
.a.b.replacement,
.replacement.c {
color: orange;
}
.test:hover,
.replacement:hover {
color: green;
}
你可以将这种操作模式视为本质上进行非破坏性搜索和替换。
¥You can think of this mode of operation as essentially doing a non-destructive search and replace.
继承选择器插值
¥Selector Interpolation with Extend
Extend is not 能够将选择器与变量相匹配。如果选择器包含变量,extend 将忽略它。
¥able to match selectors with variables. If selector contains variable, extend will ignore it.
但是,extend 可以附加到插值选择器。
¥However, extend can be attached to interpolated selector.
带有变量的选择器将不会被匹配:
¥Selector with variable will not be matched:
@variable: .bucket;
@{variable} {
color: blue;
}
.some-class:extend(.bucket) {}
并在目标选择器中使用变量扩展不匹配:
¥and extend with variable in target selector matches nothing:
.bucket {
color: blue;
}
.some-class:extend(@{variable}) {}
@variable: .bucket;
以上两个例子编译成:
¥Both of the above examples compile into:
.bucket {
color: blue;
}
但是,附加到插值选择器的 :extend
有效:
¥However, :extend
attached to an interpolated selector works:
.bucket {
color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;
编译为:
¥compiles to:
.bucket, .selector {
color: blue;
}
¥Scoping / Extend Inside @media
目前,@media
声明中的 :extend
只会匹配同一媒体声明中的选择器:
¥Currently, an :extend
inside a @media
declaration will only match selectors inside the same media declaration:
@media print {
.screenClass:extend(.selector) {}
.selector {
color: black;
}
}
.selector {
color: red;
}
@media screen {
.selector {
color: blue;
}
}
编译成:
¥compiles into:
@media print {
.selector,
.screenClass {
color: black;
}
}
.selector {
color: red;
}
@media screen {
.selector {
color: blue;
}
}
注意:扩展与嵌套 @media
声明内的选择器不匹配:
¥Note: extending does not match selectors inside a nested @media
declaration:
@media screen {
.screenClass:extend(.selector) {}
@media (min-width: 1023px) {
.selector {
color: blue;
}
}
}
这编译成:
¥This compiles into:
@media screen and (min-width: 1023px) {
.selector {
color: blue;
}
}
顶层扩展匹配所有内容,包括嵌套媒体内的选择器:
¥Top level extend matches everything including selectors inside nested media:
@media screen {
.selector {
color: blue;
}
@media (min-width: 1023px) {
.selector {
color: blue;
}
}
}
.topLevel:extend(.selector) {}
编译成:
¥compiles into:
@media screen {
.selector,
.topLevel {
color: blue;
}
}
@media screen and (min-width: 1023px) {
.selector,
.topLevel {
color: blue;
}
}
重复检测
¥Duplication Detection
目前没有重复检测。
¥Currently there is no duplication detection.
示例:
¥Example:
.alert-info,
.widget {
}
.alert:extend(.alert-info, .widget) {}
输出
¥Outputs
.alert-info,
.widget,
.alert,
.alert {
}
继承的用例
¥Use Cases for Extend
经典用例
¥Classic Use Case
经典用例是避免添加基类。例如,如果你有
¥The classic use case is to avoid adding a base class. For example, if you have
.animal {
background-color: black;
color: white;
}
并且你想要一种动物子类型来覆盖背景颜色,那么你有两个选择,首先更改你的 HTML
¥and you want to have a subtype of animal which overrides the background color then you have two options, firstly change your HTML
<a class="animal bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
background-color: brown;
}
或者简化 html 并在你的 less 中使用 extend。例如
¥or have simplified html and use extend in your less. e.g.
<a class="bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
&:extend(.animal);
background-color: brown;
}
减少 CSS 大小
¥Reducing CSS Size
Mixins 将所有属性复制到一个选择器中,这会导致不必要的重复。因此,你可以使用 extends 而不是 mixins 将选择器向上移动到你希望使用的属性,这会导致生成更少的 CSS。
¥Mixins copy all of the properties into a selector, which can lead to unnecessary duplication. Therefore you can use extends instead of mixins to move the selector up to the properties you wish to use, which leads to less CSS being generated.
示例 - 与混合:
¥Example - with mixin:
.my-inline-block() {
display: inline-block;
font-size: 0;
}
.thing1 {
.my-inline-block;
}
.thing2 {
.my-inline-block;
}
输出
¥Outputs
.thing1 {
display: inline-block;
font-size: 0;
}
.thing2 {
display: inline-block;
font-size: 0;
}
示例(带扩展):
¥Example (with extends):
.my-inline-block {
display: inline-block;
font-size: 0;
}
.thing1 {
&:extend(.my-inline-block);
}
.thing2 {
&:extend(.my-inline-block);
}
输出
¥Outputs
.my-inline-block,
.thing1,
.thing2 {
display: inline-block;
font-size: 0;
}
组合样式/更高级的混合
¥Combining Styles / A More Advanced Mixin
另一个用例是作为 mixin 的替代品 - 因为 mixins 只能与简单的选择器一起使用,所以如果你有两个不同的 html 块,但需要对两个块应用相同的样式,则可以使用 extends 来关联两个区域。
¥Another use-case is as an alternative for a mixin - because mixins can only be used with simple selectors, if you have two different blocks of html, but need to apply the same styles to both you can use extends to relate two areas.
示例:
¥Example:
li.list > a {
}
button.list-style {
&:extend(li.list > a);
}