Less学习教程五

           本文从http://lesscss.org/features/#extend-feature翻译而来,增加了少量说明。由于英文水平有限,某些地方采用了我所理解的意              思,而不是直译。

       扩展

扩展是一个将外层选择符与其引用的选择符进行合并的伪类。

v1.4.0引入

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

在上述规则集中,:extend选择器将所述“扩展”选择器(nav ul)到.inline类中,不管.inline类在哪里出现。声明块将保持原样,但不对扩展进行任何引用(因为扩展不是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这个规则的输出:扩展在输出之前被删除,选择器块保持原样。如果该块中未设置任何属性,则将该块从输出中删除(但扩展仍然可能影响其他选择器)。

这条规则很简单,就是说要扩展另外一个规则的选择器部分,用逗号隔开。也可以认为是,现在的规则想“继承”其他规则的属性。我刚看到时,是有一个疑问的,什么时候要用扩展,为什么会有这种用法,我用mixins不一样能得到同样的功能?先看看输出部分,可以等价于:

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

可以看到color: red;这个属性重复了一次。这个例子比较简单,如果.inline属性比较多的话,那么重复的属性也会比较多。可以看出用扩展会让css文件比较小。

另外,如果我们有如下的代码,用扩展可以直接引用,但是却无法使用mixins。

ulclass>liclass{
    background-color:blue;
}
//无法直接用mixins,但是可以用extend
.nav-li{
   &:extend(ulclass>liclass);
}

我们可以在扩展用例部分看到其他的例子,在此提前说明是为了让您不至于带着太多疑问往下读。 

         扩展语法

扩展要么附加到选择器,要么放置在规则集中。看起来像是带有选择器参数的伪类,可选择性地在其后增加关键字all

例:

.a:extend(.b) {}

// 放置在规则集中也可以
.a {
  &:extend(.b);
}
.c:extend(.d all) {
  // 将扩展所有和".d" 有关的规则集,例如".x.d" or ".d.x"
}
.c:extend(.d) {
  // 只会扩展选择器为".d"的规则集
}

它可以包含一个或多个要扩展的类,以逗号分隔。

例:

.e:extend(.f) {}
.e:extend(.g) {}

// 可以写成如下的形式
.e:extend(.f,.g) {}

         扩展附加到选择器

附加到选择器的扩展看起来像一个带有选择器作为参数的普通伪类。一个选择器可以包含多个extend子句,但是所有扩展都必须在选择器的末尾。

  • 在选择器之后扩展:pre:hover:extend(div pre)
  • 选择器和扩展之间允许有空格:pre:hover :extend(div pre)
  • 允许多个扩展:pre:hover:extend(div pre):extend(.bucket tr)。注意,这与pre:hover:extend(div pre, .bucket tr)是相同的。
  • 这是不允许的:pre:hover:extend(div pre).nth-child(odd)。扩展必须是最后一个。

如果规则集包含多个选择器,则它们中的任何一个都可以具有extend关键字。在一个规则集中扩展的多个选择器:

.big-division,
.big-bag:extend(.bag),
.big-bucket:extend(.bucket) {
  font-size: 16px;
}

.bag{
    color: red;
}

.bucket{
    color: blue;
}

 输出是

.big-division,
.big-bag,
.big-bucket {
  font-size: 16px;
}
.bag,
.big-bag {
  color: red;
}
.bucket,
.big-bucket {
  color: blue;
}

         扩展内部规则集

可以使用&:extend(selector)语法将扩展放置在规则集的主体中。这是一种简写方式,可替换将其放入该规则集的每个选择器中。

在体内延伸:

pre:hover,
.some-class {
  &:extend(div pre);
}

与在每个选择器之后添加扩展名完全相同:

pre:hover:extend(div pre),
.some-class:extend(div pre) {}

         扩展嵌套选择器

扩展可以匹配嵌套选择器。如以下less代码:

.bucket {
  tr { // 嵌套规则集
    color: blue;
  }
}
.some-class:extend(.bucket tr) {} // 这种表达式是可以的

输出为

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

从本质上讲,扩展将查找编译后的CSS,而不是原始的less文件。

例:

.bucket {
  tr & { // 嵌套规则集,但是&放于后面
    color: blue;
  }
}
.some-class:extend(tr .bucket) {} // 这种写法是正确的

输出为

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

         扩展的精确匹配

扩展在默认情况下查找完全匹配选择器。在其他情况下,选择器前面是否使用星号意义是一样的,两个不同的nth表达式也可能具有相同含义,但是在扩展时它们必须具有相同的形式才能匹配。唯一的例外是属性选择器中的引号,Less能够推断出它们的含义相同并匹配它们。

例:

.a.class,
.class.a,
.class > .a {
  color: blue;
}
.test:extend(.class) {} // 上面三种选择器均不匹配

前置星号不重要,选择器*.class.class是等效的,但扩展时与它们不匹配:

*.class {
  color: blue;
}
.noStar:extend(.class) {} // 无法匹配*.class选择器

输出

*.class {
  color: blue;
}

伪类的顺序很重要:选择器link:hover:visitedlink:visited:hover匹配相同的元素集,但Less扩展时将它们视为不同的元素:

link:hover:visited {
  color: blue;
}
.selector:extend(link:visited:hover) {}

输出

link:hover:visited {
  color: blue;
}

         第n个表达式

第N个表达形式很重要。Nth个表达式1n+3n+3是等效的,但extend与它们不匹配:

:nth-child(1n+3) {
  color: blue;
}
.child:extend(:nth-child(n+3)) {}   //与1n+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;
}

         扩展“全部”

当把扩展参数的最后一个指定为all关键字时,它告诉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;
}

您可以认为这种操作方式实质上是在进行无损搜索和替换。

 

         带扩展的选择器插值

扩展是能够与带变量的选择器匹配。如果选择器包含变量,扩展时将忽略它。

但是,扩展可以附加到插值选择器。

具有变量的选择器将匹配不成功:

@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) {} // 媒体查询内的扩展
  .selector { // 可以匹配,在同一个媒体查询内
    color: black;
  }
}
.selector { // 顶级规则中,扩展将忽略它
  color: red;
}
@media screen {
  .selector {  // 在另外的媒体查询规则中,扩展将忽略它
    color: blue;
  }
}

编译成:

@media print {
  .selector,
  .screenClass { //在同一个媒体查询内,可以匹配到
    color: black;
  }
}
.selector { // 顶级规则中,扩展将忽略它
  color: red;
}
@media screen {
  .selector { // 在另外的媒体查询规则中,扩展将忽略它
    color: blue;
  }
}

注意:扩展与嵌套@media声明中的选择器不匹配:

@media screen {
  .screenClass:extend(.selector) {} // 媒体查询中的扩展
  @media (min-width: 1023px) {
    .selector {  // 媒体查询中的嵌套规则,实际与上面的extend不在同一个媒体查询中,被忽略
      color: blue;
    }
  }
}

编译成:

@media screen and (min-width: 1023px) {
  .selector { //扩展被忽略掉了
    color: blue;
  }
}

顶级扩展匹配所有内容,包括嵌套媒体中的选择器:

@media screen {
  .selector {  //嵌套规则中的选择器,顶层的扩展可以匹配它
    color: blue;
  }
  @media (min-width: 1023px) {
    .selector {  //嵌套规则中的选择器,顶层的扩展可以匹配它
      color: blue;
    }
  }
}

.topLevel:extend(.selector) {} //顶层的扩展可以匹配各种媒体查询中的选择器

编译成:

@media screen {
  .selector,
  .topLevel { //媒体查询中的选择器被扩展了
    color: blue;
  }
}
@media screen and (min-width: 1023px) {
  .selector,
  .topLevel { //嵌套媒体查询中的选择器被扩展了
    color: blue;
  }
}

         重复检测

目前没有重复检测。

例:

.alert-info,
.widget {
  /* 声明 */
}

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

将输出

.alert-info,
.widget,
.alert,
.alert {//.alert有重复
  /* 声明 */
}

         扩展用例

经典用例

经典的用例是避免添加基类。例如,如果您有

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

并且您想要一个animal的子类型来覆写背景色,那么您有两个选择,首先是更改HTML,添加一个bear类

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

或者您使用扩展,会有更加简单的html代码,只使用bear类。例如

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

减少CSS大小

Mixins将所有属性复制到选择器中,这可能导致不必要的重复。因此您可以使用扩展而不是mixins,来将选择器移到要使用的属性上,这将减少所生成CSS的大小。

示例-使用mixin:

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

输出

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

示例(用扩展):

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

产出

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

组合样式/更高级的mixin

另一个用例是mixin的替代方案,因为mixin只能与简单的选择器一起使用。如果您有两个不同的html块,但需要对两者使用相同的样式,则可以使用扩展来关联两个区域。

例:

li.list > a {
  // list styles
}
button.list-style {
  &:extend(li.list > a); // 使用相同的list styles
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值