官方文档是这么介绍Extend的
Extend is a Less Pseudo-Class which merges the selector it is put on with ones that match what it references.
简单翻译就是Extend是less的伪类选择器,这个伪类选择器会将引用它的选择器与匹配它的选择器合并(英语太渣, 不知道翻译的是否准确,下面用例子来说明)
.box1 {
&:extend(.box2);
background-color: #eee;
margin-bottom: 10px;
}
.box2 {
width: 100px;
height: 100px;
background-color: #333;
}
编译为:/* line 2, http://localhost/about-less/styles.less */
.box1 {
background-color: #eee;
margin-bottom: 10px;
}
/* line 8, http://localhost/about-less/styles.less */
.box2,
.box1 {
width: 100px;
height: 100px;
background-color: #333;
}
此时如果将.box1和.box2交换一下顺序,会有些变化发生
.box2 {
width: 100px;
height: 100px;
background-color: #333;
}
.box1 {
&:extend(.box2);
background-color: #eee;
margin-bottom: 10px;
}
编译为:/* line 1, http://localhost/about-less/styles.less */
.box2,
.box1 {
width: 100px;
height: 100px;
background-color: #333;
}
/* line 6, http://localhost/about-less/styles.less */
.box1 {
background-color: #eee;
margin-bottom: 10px;
}
因为less文件中顺序的颠倒,导致最后编译出的结果中,样式顺序也相应的颠倒过来。官方文档的是这样解释的:In the rule set above, the :extend selector will apply the "extending selector"(.box1) onto the .box2 class wherever the .box2 class appears. The declaration block
will be kept as-is, but without any reference to the extend (because extend isn't css).简单翻译:extend会把应用extend的选择器运用到extend所匹配的选择器出现的位置Extend syntax(Extend语法)
The extend is either attached to a selector or placed into a ruleset. It looks like a pseudoclass with selector parameter optionally followed by the keyword
由英语渣渣再次简单翻译:extend要么隶属于选择器,要么放入一个规则集(extend的位置要么像伪类选择器一样,跟在某个选择器后面,要么放入一个具体的css样式范围内)。它看起来就像一个跟在关键字后面带有可选参数的伪类选择器。
.box1 {
&:extend(.box2);
background-color: #eee;
margin-bottom: 10px;
}
/*上下分别代表了extend的两种写法*/
.box1:extend(.box2) {
background-color: #cf002d;
margin-bottom: 10px;
}
Extending nested Selectors(嵌套选择器)
.box2 {
width: 100px;
height: 100px;
background-color: #333;
.box2Child{
color: #fff;
}
}
.box1:extend(.box2 .box2Child) {
background-color: #cf002d;
margin-bottom: 10px;
}
下面这种写法与上面等价.box2 {
width: 100px;
height: 100px;
background-color: #333;
}
.box2 .box2Child {
color: #fff;
}
.box1:extend(.box2 .box2Child) {
background-color: #cf002d;
margin-bottom: 10px;
}
但是如下面这种写法是匹配不到元素的.box2 {
width: 100px;
height: 100px;
background-color: #333;
}
/*去掉父元素后,extend匹配不到元素*/
.box2Child {
color: #fff;
}
.box1:extend(.box2 .box2Child) {
background-color: #cf002d;
margin-bottom: 10px;
}
Exact Matching with Extend(精确匹配)
.a.class,
.class.a,
.class > .a {
color: blue;
}
.test:extend(.class) {} // this will NOT match the any selectors above
(不是很清楚.a.class是一种什么样的选择器,难道是类似div.a.class这种?)*.class {
color: blue;
}
.noStar:extend(.class) {} // this will NOT match the *.class selector
上面这个例子仍然不能匹配到link:hover:visited {
color: blue;
}
.selector:extend(link:visited:hover) {}
上面例子尽管只是伪类选择器的顺序不一样,但是less仍然不能匹配到nth expression(nth表达式)
1n+3
and n+3
are
equivalent, but extend will not match them(less是支持nth表达式的,不过1n+3与n+3虽然意义是相同的,但在less里则是不同的):nth-child(1n+3) {
color: blue;
}
.child:extend(n+3) {}
编译为::nth-child(1n+3) {
color: blue;
}
Quote
type in attribute selector does not matter. All of the following are equivalent.(在less规则中,属性选择器的引号是没有实际作用的,有无引号,单引号还是双引号都没有关系)[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"(all关键词)
.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;
}
Selector Interpolation with Extend(Extend选择器插值)
Selector with variable will not be matched(Extend可以跟在变量选择其后面被引用,但是却不能匹配变量选择器,这是一个尚未解决,却不容易改变的特征)
@variable: .bucket;
@{variable} { // interpolated selector
color: blue;
}
.some-class:extend(.bucket) {} // does nothing, no match is found
.bucket {
color: blue;
}
.some-class:extend(@{variable}) {} // interpolated selector matches nothing
@variable: .bucket;
但是Extend却可以跟在变量选择器后面工作.bucket {
color: blue;
}
@{variable}:extend(.bucket) {}
@variable: .selector;
编译为:.bucket, .selector {
color: blue;
}
Scoping / Extend Inside @media(媒体查询里的作用域/Extend)(暂时用不到,先把文档中的内容搬过来,以后再翻译)
@media print {
.screenClass:extend(.selector) {} // extend inside media
.selector { // this will be matched - it is in the same media
color: black;
}
}
.selector { // ruleset on top of style sheet - extend ignores it
color: red;
}
@media screen {
.selector { // ruleset inside another media - extend ignores it
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
written inside a media declaration does not match selectors inside nested declaration:@media screen {
.screenClass:extend(.selector) {} // extend inside media
@media (min-width: 1023px) {
.selector { // ruleset inside nested media - extend ignores it
color: blue;
}
}
}
编译为:@media screen and (min-width: 1023px) {
.selector { /* ruleset inside another nested media was ignored */
color: blue;
}
}
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;
}
}
Duplication Detection(复制检测)
.alert-info,
.widget {
/* declarations */
}
.alert:extend(.alert-info, .widget) {}
编译为:.alert-info,
.widget,
.alert,
.alert {
/* declarations */
}
Use Cases for Extend()
e.g 1<a class="animal bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
background-color: brown;
}
上面的例子可以用下面这种写法<a class="bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
&:extend(.animal);
background-color: brown;
}
e.g
2.my-inline-block() {
display: inline-block;
font-size: 0;
}
.thing1 {
.my-inline-block;
}
.thing2 {
.my-inline-block;
}
上面例子可以用下面这种写法.my-inline-block {
display: inline-block;
font-size: 0;
}
.thing1 {
&:extend(.my-inline-block);
}
.thing2 {
&:extend(.my-inline-block);
}
其编译结果分别为:.thing1 {
display: inline-block;
font-size: 0;
}
.thing2 {
display: inline-block;
font-size: 0;
}
.my-inline-block,
.thing1,
.thing2 {
display: inline-block;
font-size: 0;
}
很明显,减少了css代码