继承
Extend是一个伪属性较少的类,它将放置的选择器与它引用的选择器进行合并。
Released v1.4.0
nav ul {
&:extend(.inline);
background: blue;
}
在上面的规则集中,:extend
选择器会把"扩展选择器" nav ul
应用到.inline
类出现的地方。声明块保持原样,但不引用extend(因为extend不是css)。
所以如下所示:
nav ul {
&:extend(.inline);
background: blue;
}
.inline {
color: red;
}
编译后:
nav ul {
background: blue;
}
.inline,
nav ul {
color: red;
}
注意nav ul:extend(.inline)选择器的输出是nav ul——扩展在输出之前被移除,选择器保持不变。如果该块中没有任何属性,那么它将从输出中删除(但extend仍然可能影响其他选择器)。
扩展语法
扩展要么附加到选择器,要么放置到规则集中。它看起来像一个伪类,参数selector可选,后面跟all关键字:
举例:
.a:extend(.b) {}
// 上面的代码块和下面的代码块做同样的事情
.a {
&:extend(.b);
}
.c:extend(.d all) {
// extends all instances of ".d" e.g. ".x.d" or ".d.x"
}
.c:extend(.d) {
// 仅扩展选择器输出为“.d”的实例
}
它可以包含一个或多个要扩展的类,用逗号分隔。
举例:
.e:extend(.f) {}
.e:extend(.g) {}
// 上面和下面做同样的事情
.e:extend(.f, .g) {}
延伸连接到选择器
连接到选择器的Extend看起来像一个普通的伪类,参数是selector。一个选择器可以包含多个extend子句,但所有的extends都必须位于选择器的末尾。
在选择器之后扩展:pre:hover: Extend (div pre)。
在selector和extend之间可以有空格:pre:hover:extend(div pre)。
允许多重扩展:pre:hover:extend(div pre):extend(。注意,这和pre:hover:extend(div pre, .bucket tr)是一样的。
不允许:pre:hover:extend(div pre).nth-child(odd)。延长必须是最后的。
如果一个规则集包含多个选择器,其中任何一个都可以使用extend关键字。在一个规则集中使用多个extend选择器:
.big-division,
.big-bag:extend(.bag),
.big-bucket:extend(.bucket) {
// body
}
扩展规则集内部
Extend可以使用&:Extend (selector)语法放置到规则集的主体中。将extend放置在主体中是将其放置到该规则集的每个选择器中的一种快捷方式。
在身体内部延伸:
pre:hover,
.some-class {
&:extend(div pre);
}
这与在每个选择器后面添加一个extend完全相同:
前:徘徊:扩展(div)之前,
.some-class:extend(div pre) {}
扩展嵌套选择器
Extend能够匹配嵌套的选择器。
举例:
.bucket {
tr { // nested ruleset with target selector
color: blue;
}
}
.some-class:extend(.bucket tr) {} // nested ruleset is recognized
编译后:
.bucket tr,
.some-class {
color: blue;
}
从本质上讲,extend关注的是已编译的css,而不是原始的less。
举例:
.bucket {
tr & { // nested ruleset with target selector
color: blue;
}
}
.some-class:extend(tr .bucket) {} //已识别嵌套规则集
编译后:
tr .bucket,
.some-class {
color: blue;
}
与Extend的精确匹配
默认情况下,Extend会查找选择器之间的精确匹配。选择器是否使用前导星并不重要。两个第n个表达式具有相同的含义并不重要,它们需要具有相同的形式才能匹配。唯一的例外是属性选择器中的引号,less知道它们具有相同的含义并与它们匹配。
举例:
.a.class,
.class.a,
.class > .a {
color: blue;
}
.test:extend(.class) {} // 这个匹配不到
上面的任意选择器
主演确实很重要。选择器*.class和.class是等效的,但extend与它们不匹配:
*.class {
color: blue;
}
.noStar:extend(.class) {} // 这个匹配不到 *.class 选择器
编译后:
*.class {
color: blue;
}
伪类的顺序很重要。选择器link:hover:visited和link:visited:hover匹配同一组元素,但extend将它们视为不同:
link:hover:visited {
color: blue;
}
.selector:extend(link:visited:hover) {}
编译后:
link:hover:visited {
color: blue;
}
第n个表达式
第N种表达形式确实很重要。第n个表达式1n+3和n+3是等价的,但extend将与它们不匹配:
:nth-child(1n+3) {
color: blue;
}
.child:extend(:nth-child(n+3)) {}
编译后:
:nth-child(1n+3) {
color: blue;
}
属性选择器中的引号无关紧要。以下所有内容都是等效的。
[title=identifier] {
color: blue;
}
[title='identifier'] {
color: blue;
}
[title="identifier"] {
color: blue;
}
.noQuote:extend([title=identifier]) {}
.singleQuote:extend([title='identifier']) {}
.doubleQuote:extend([title="identifier"]) {}
编译后:
[title=identifier],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
[title='identifier'],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
[title="identifier"],
.noQuote,
.singleQuote,
.doubleQuote {
color: blue;
}
Extend “all”
当你用extend的最后一个参数来指定来制定所有的关键字,它会告诉Less将该选择器匹配为另一个选择器的一部分。选择器将被复制,然后仅选择器的匹配部分将被扩展替换,从而形成一个新的选择器。
举例:
.a.b.test,
.test.c {
color: orange;
}
.test {
&:hover {
color: green;
}
}
.replacement:extend(.test all) {}
编译后:
.a.b.test,
.test.c,
.a.b.replacement,
.replacement.c {
color: orange;
}
.test:hover,
.replacement:hover {
color: green;
}
您可以将这种操作模式视为本质上进行非破坏性搜索和替换。
带延伸的选择器插值
Extend无法将选择器与变量匹配。若选择器包含变量,则扩展将忽略它。
但是,可以将扩展附加到插值选择器。
带有变量的选择器将不匹配:
@variable: .bucket;
@{variable} { // 插值 选择器
color: blue;
}
.some-class:extend(.bucket) {} // 匹配不到
并且在目标选择器中使用变量进行扩展时不匹配任何内容:
.bucket {
color: blue;
}
.some-class:extend(@{variable}) {} //匹配不到
@variable: .bucket;
上面两个都会被编译成
.bucket {
color: blue;
}
不过,:extend放到插值选择器后面就有效
.bucket {
color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;
编译后:
.bucket, .selector {
color: blue;
}
在@media内部范围界定/扩展
目前,@media声明中的:extend将只匹配同一媒体声明中的选择器:
@media print {
.screenClass:extend(.selector) {} // extend inside media
.selector { // 会被extend匹配,因为这个在@media之内
color: black;
}
}
.selector { // 会被extend忽略
color: red;
}
@media screen {
.selector { // 在另一个@media内,也会被忽略
color: blue;
}
}
编译后:
@media print {
.selector,
.screenClass { /* ruleset inside the same media was extended */
color: black;
}
}
.selector { /* ruleset on top of style sheet was ignored */
color: red;
}
@media screen {
.selector { /* ruleset inside another media was ignored */
color: blue;
}
}
注意:extend不会匹配不在同一层的@media内
@media screen {
.screenClass:extend(.selector) {} /* extend在@media内 */
@media (min-width: 1023px) {
.selector { /* 在下一层的@media,会被忽略 */
color: blue;
}
}
}
编译后:
@media screen and (min-width: 1023px) {
.selector { /* 在另外一个层级的@media会被忽略 */
color: blue;
}
}
第一层css(根)的extend匹配midia的所有层级
Top level extend matches everything including selectors inside nested media:
@media screen {
.selector { /* ruleset inside nested media - top level extend works */
color: blue;
}
@media (min-width: 1023px) {
.selector { /* ruleset inside nested media - top level extend works */
color: blue;
}
}
}
.topLevel:extend(.selector) {} /* top level extend matches everything */
编译后:
@media screen {
.selector,
.topLevel { /* ruleset inside media was extended */
color: blue;
}
}
@media screen and (min-width: 1023px) {
.selector,
.topLevel { /* ruleset inside nested media was extended */
color: blue;
}
}
没有重复检测。
举例:
.alert-info,
.widget {
/* declarations */
}
.alert:extend(.alert-info, .widget) {}
编译后:
.alert-info,
.widget,
.alert,
.alert {
/* declarations */
}
Extend的用例
经典用例
经典的用例是避免添加基类。例如,如果您有
.animal {
background-color: black;
color: white;
}
如果你想有一个覆盖背景颜色的动物子类型,那么你有两个选项,首先更改HTML
<a class="animal bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
background-color: brown;
}
或者简化了html并在您的less中使用extend。例如
<a class="bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
&:extend(.animal);
background-color: brown;
}