less新手入门(一) 变量、extend扩展

前景提要

个人在学习less时候的学习笔记及个人总结,主要是结合less中文网来学习的,但是说是中文网并不是中文呀,看起来很耽误时间,为了避免以后再次看的时候还要翻译思考,特意做此总结,方便以后查阅。

概述

Less是Css的一种扩展,完全兼容css语法,我们在使用中可以直接 link 引入也可以,通过编译工具,将less 编译成 css后再引入;

目录:

一、变量

二、Extend  扩展

三、Mixin  混合

四、带参数 Mixin

五、作为函数使用 Mixin

六、@import  导入指令

七、@improt 导入选项

八、Mixin Guards

九、CssGuards、循环、合并、父选择器

 此篇博客原创博客地址:http://www.cnblogs.com/fighxp/

 


一、变量

1. 定义:

使用 @ 符号来定义变量 ,在Less中开头是 @ 则是变量,关于变量的命名方法,大家可以参考js中命名的规则,毕竟是做前端的,有着统一的习惯有助于我们统一风格。个人推荐变量名的命名规则使用驼峰命名法。第一个单词首写字母小写,从第二个开始,单词首写字母大写。如boxAaa,boxBbbb,boxContainer,……,当然也是可是使用香肠命名法用下划线“_”来命名。如,box_main,border_bottom,……

2. 使用:

在样式属性值中使用时,直接用 @variable 即可调用变量;

在其他地方,包括选择器名称、属性名称、URL和@import语句使用时,变量必须以插值的形式使用,例如:

@variable: 200px; //定义变量作为样式属性值使用
@classname: .nav_a; //变量值不可用中划线,此变量作为插值用于选择器名称


@{classname}{ //作为插值 必须加 {}
    width: @variable; //作为属性值直接调用
}

输出:

.nav_a {
  width: 200px;
}

3. 变量特点:变量是懒加载的,不要求一定在使用之前声明。

4.  在存在多个同名变量时,变量如何获取值?

和css规则类似,在同时定义一个变量两次时,会在使用变量的地方,从当前范围向上搜索,使用变量最后定义内的属性值。

@var: 0;
.class1 {
  @var: 1;
  .class {
    @var: 2;
    three: @var;
    @var: 3;
  }
  one: @var;
}

编译输出:

.class1 .class {
  three: 3;
}
.class {
  one: 1;
}

5. 变量的其它使用技巧:初始值

在定义变量时可以给变量赋一个初始值,后期在使用中通过重新定义或函数 来覆盖原本的初始值

 

二、extend 

:extend是一个伪类,使用它的选择器,将和它引用的选择器一起使用它引用的选择器的样式,如:

先定义一个扩展的选择器,我们就叫它 .a,然后定义一个选择器 .b(用来扩展),在 .a内使用 :extend 扩展,代码如下

.a{
    &:extend(.b);  //这里的 & 为 父选择符,代表的 父选择符 .a 扩展 .b
    font-size: 12px;
}
.b{
    font-weight: bold;
}

输出:

.a {
  font-size: 12px;
}
.b,
.a {
  font-weight: bold;  //这里 a 扩展也引用了 b 的样式
}

注意:如果这里的 .b 内没有定义任何样式,那么编译后的css中, 不会有 .b 的任何输出,相应的 .a 也不会扩展到任何样式

1.  :extend 语法

:extend()可以附加到选择器后面,也可以放到样式规则中,它看起来就像是一个选择器的伪类,在使用的时候我们可以选择性的加上 关键字 all

语法示例:

.a:extend(.b){}   //方法一:附加到选择器后
.a{
    &:extend(.b)    // 方法二:写在样式规则中
}

 all关键字的使用详解 见 第7条

2. :extend() 直接使用在选择器后

每个选择器可以使用多个 :extend() 语句, 但是所使用的 :extend() 语句必须放在选择器末尾,下面详细描述

  • 在选择器之后: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必须在选择器末尾。

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

.a,
.b:extend(.bag),
.c:extend(.bucket) {
  // 这里啊a,b,c  3个选择器都可以使用 :extend
}

 3.  :extend()在样式规则中使用

把 :extend() 放到多个选择器共用的样式规则集中,是把样式扩展到每个选择器的最佳选择。

下面来个对比:

直接把: extend() 放到样式规则中,

.a,
.c,
.d{
    &:extend(.b);
}
.b{
    font-size: 12rem;
}

输出:

.b,
.a,
.c,
.d {
  font-size: 12rem;
}

 

如果把 :extend 放在选择器后,那么需要单独对 .a , .c , .d单独处理,会增加代码量,后期维护也很繁琐

.a:extend(.b){}
.c:extend(.b){}
.d:extend(.b){}

4. 扩展 嵌套选择器

将:extend() 直接放在选择器后,可以扩展嵌套选择器样式规则,示例:

.my-table{
   .my-tr{
        font-size: 50px;
    }
}

.mt-other-table:extend(.my-table .my-tr){}

 

5. :extend中选择符的精确匹配

默认情况下,:extend() 中查找选择器的原则是精准匹配,就算是 选择器 在开始使用(例如  .class .a)也没用;或者是两个选择符表达式韩式一样,那在匹配过程中也没有意义,:extend()中选择器只能匹配到 具有相同形式的选择器。唯一例外的是属性选择器中的 引号 ,Less知道它们具有相同的含义并匹配它们。

示例:

.a.class,
.class.a,
.class>.a{
    color: blue;
}
.test:extend(.class) {}

 

编译下,命令行中报错了..... 没有匹配到  .class

$ lessc refer.less > refer.css
extend ' .class' has no matches

 选择器前面的符号是很重要的, 虽然 *.class{} 和.class{}是一样的,但是在:extend(.class)中无法匹配到 *.class

*.class {
  color: blue;
}
.noStar:extend(.class) {} // 不会匹配到 *.class 

 多个伪类在 :extend() 中的顺序也很重要,选择器link:hover:visitedlink:visited:hover匹配相同的一组元素,但 :extend() 将它们视为不同。

link:hover:visited {
  color: blue;
}
.selector:extend(link:visited:hover) {}  //此时无法匹配到link:hover:visited

 

6.  使用 n 的选择器 、使用属性筛选的选择器

6.1 1n+3n+3相当,但:extend不会匹配他们:

:nth-child(1n+3) {
  color: blue;
}
.child:extend(n+3) {} // 无法匹配

 

6.2 在属性选择器中的引用类型无关紧要。以下所有都是相同的。

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

.noQuote:extend([title=identifier]) {}
.singleQuote:extend([title='identifier']) {}
.doubleQuote:extend([title="identifier"]) {}

 

7. :extend() 中关键字 all的使用

在使用extend时,在末尾添加 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;
}

 

8. 选择器插值与extend 

:extend不能将选择器与变量相匹配。如果选择器包含变量,扩展将忽略它;

变量无法与选择器匹配:

@variable: .bucket; //定义变量
@{variable} { // 变量插值
  color: blue;
}
.some-class:extend(.bucket) {} //没有做任何工作,此时无法匹配到 .selector

 

 输出:仅仅只输出了 .selector 的样式规则

.bucket {
  color: blue;
}

 

 但是,将 :extend 扩展直接写在 变量选择器后,可正常使用,将上例代码改为如下:

.bucket{
    color: blue;
}
@variable: some-class; //此时有中划线,将 . 移至变量插值前,否则会报错
.@{variable}:extend(.bucket){}  // 在变量选择器后使用 :extend ,正常编译

 

正常编译:

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

 

9. 作用范围 / extend 在 @media 中的使用

1. 在 media 媒体声明中写入的 extend 只匹配同一媒体声明中的选择器:

@media print {
  .screenClass:extend(.selector) {} // extend inside media
  .selector { // 这会被匹配到 - 以为和extend在同一个media内
    color: black;
  }
}
.selector { // 规则集在上一个样式中 - extend 将忽略这
  color: red;
}
@media screen {
  .selector {  // r规则集在另一个样式中 - extend 将忽略这
    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;
  }
}

2. 在媒体声明中写入的 extend ,不匹配其嵌套声明中的选择器:

@media screen {
  .screenClass:extend(.selector) {} // extend inside media
  @media (min-width: 1023px) {
    .selector {  // css在media内部嵌套 - extend 将忽略它
      color: blue;
    }
  }
}

输出:

@media screen and (min-width: 1023px) {
  .selector { /* ruleset inside another nested media was ignored */
    color: blue;
  }
}

3. 顶级 :extend 将匹配所有内容,包括嵌套媒体中的选择器

@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) {} /* 定层级 :extend 匹配所有 */

输出:

@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;
  }
}

10. 重复检测 - Duplication Detection

 在使用:extend 时,less目前没有检测重复的 功能

.alert-info,
.widget {
  /* declarations */
}

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

输出:

.alert-info,
.widget,
.alert,
.alert {
  /* declarations */
}

11.  Extend案例扩展

1.典型用例

典型的用例是避免在html添加  基本选择器类别  。例如,如果你有

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

然后你想要一种重写 background-color 的class类 ,这时你有两个方法,第一种方法是:改变你的HTML,添加另一个选择器类 bear

<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;
}

2. 减少css大小

mixin将所有属性复制到一个选择器中,这会导致不必要的重复。因此,您可以使用 :extend 而不是mixin将选择器移到您希望使用的属性,这样会大大减少生成的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;
}

改写使用 :extend( )

.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;
}

3. 结合样式 / 更高级的混合

另一个用例是mixin的替代方案——因为mixin只能与简单的选择器一起使用,如果您在html上有两个不同的块,但是它们需要应用相同的样式到,那么您可以使用 :extend 来关联两个区域。

li.list > a {
  // list styles
}
button.list-style {
  &:extend(li.list > a); // use the same list styles
}

 

  此篇博客原创博客地址:http://www.cnblogs.com/fighxp/

posted @ 2017-12-22 11:11  沉着前进  阅读(20189)  评论(0编辑  收藏  举报