变量、混合、嵌套

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-06-25

变量

在 less 中使用@来申明一个变量

作为普通属性值

@width: 10px;
@height: @width + 10px;

#header {
  width: @width;
  height: @height;
}

作为选择器

@my-selector: banner;

.@{my-selector} {
  font-weight: bold;
  line-height: 40px;
  margin: 0 auto;
}

// 编译为
.banner {
  font-weight: bold;
  line-height: 40px;
  margin: 0 auto;
}

作为URL

@images: "../img";

body {
  color: #444;
  background: url("@{images}/white-sand.png");
}

在导入语句中使用

@themes: "../../src/themes";

@import "@{themes}/tidal-wave.less";

作为属性key

@property: color;

.widget {
  @{property}: #0ee;
  background-@{property}: #999;
}

// 编译为
.widget {
  color: #0ee;
  background-color: #999;
}

可变变量

你可以使用另一个变量定义一个变量的名字。

@primary:  green;
@secondary: blue;

.section {
  @color: primary;

  .element {
    color: @@color;
  }
}

// 编译为
.section .element {
  color: green;
}

变量存在声明提升

你可以先使用一个变量,而在之后再对其进行赋值,类似于JS中的函数声明提升。

.lazy-eval {
  width: @var; // 先使用
  @a: 9%;  // 声明变量a为 9%
}

@var: @a; // 等同于声明 @var: 9%
@a: 100%; // 修改变量a,但不会影响变量var

// 编译为
.lazy-eval {
  width: 9%;
}

直接引用某个属性的属性值 (3.0.0+)

使用 $ + 属性名直接引用其属性值。如果

.widget {
  color: #efefef;
  background-color: $color;
}

// 编译为
.widget {
  color: #efefef;
  background-color: #efefef;
}

// 有多个color时,引用当前范围中,最终的那个值
.block {
  color: red; 
  .inner {
    background-color: $color;  // 会引用blue
  }
  color: blue;  
} 

// 编译为
.block {
  color: red; 
  color: blue;  
} 
.block .inner {
  background-color: blue; 
}

混合

混合就是将一系列属性从一个规则集引入到另一个规则集的方式

普通混合

.my-mixin {
  color: black;
}

.class {
  .my-mixin(); // 也可以不要括号,直接写作 .my-mixin; 但是这种写法是属于 deprecated
}

// 编译为
.my-mixin {
  color: black;
}

.class {
  color: black;
}

可以看到 .my-mixin定义混合,不仅能被当做混合“调用”,同样也能当做 类选择器 编译到 css 中。

不带输出的混合

.my-mixin() {
  color: black;
}

.class {
  .my-mixin(); // 也可以不要括号,直接写作 .my-mixin; 但是这种写法是属于 deprecated
}

// 编译为
.class {
  color: black;
}

使用 .my-mixin() 定义的混合,是不会编译到 css 中的。

带参数的混合

.color-mixin(@fontColor, @bgColor) {
  width: 100px;
  height: 100px;
  color: @fontColor;
  background-color: @bgColor;
}

.class {
  .color-mixin(red, blue)
}

// 编译为
.class {
  width: 100px;
  height: 100px;
  color: red;
  background-color: blue;
}

带参数且带默认值的混合

.color-mixin(@fontColor, @bgColor: blue) {
  width: 100px;
  height: 100px;
  color: @fontColor;
  background-color: @bgColor;
}

.classA {
  .color-mixin(red)
}

.classB {
  .color-mixin(red, green)
}

// 编译为
.classA {
  width: 100px;
  height: 100px;
  color: red;
  background-color: blue;
}

.classB {
  width: 100px;
  height: 100px;
  color: red;
  background-color: green;
}

命名参数

当有多个参数有默认值的时候,可以指定传的值是赋给哪个参数的。

.color-mixin(@fontColor, @bgColor: blue, @fontSize: 12px) {
  width: 100px;
  height: 100px;
  color: @fontColor;
  background-color: @bgColor;
  font-size: @fontSize;
}


.class {
  .color-mixin(red, @fontSize: 14px) // 指定参数是传给 @fontSize变量的
}

// 编译为
.class {
  width: 100px;
  height: 100px;
  color: red;
  background-color: blue;
  font-size: 14px;
}

包含选择器的混合

.my-mixin(){
  color: black;
  span {
  display: inline-block;
  }
  
  &:hover {
    color: blue
  }
}

.class {
  .my-mixin();
}

// 编译为
.class {
  color: black;
}
.class span {
  display: inline-block;
}
.class:hover {
  color: blue;
}

匹配模式

在定义混合的时候,可以使用第一个作为模式匹配符,使用的时候通过传参对应的模式匹配符采用。

.my-border-color(all, @c) {
  border-color: @c;
}

.my-border-color(l, @c, @w) {
  border-left-color: @c;
  border-left-width: @w; 
}

.my-border-color(r, @c, @w) {
  border-right-color: @c;
  border-right-width: @w; 
}


.class {
  .my-border-color(all, red) // 匹配 all 
}

.classA {
  .my-border-color(l, red, 2px); // 匹配 l
  .my-border-color(r, green, 2px); // 匹配 r
}

// 编译为
.class {
  border-color: red;
}
.classA {
  border-left-color: red;
  border-left-width: 2px;
  border-right-color: green;
  border-right-width: 2px;
}

在使用匹配模式的时候,可以使用@直接定义变量,用来匹配参数个数。

.my-border-color(all, @c) {
  border-color: @c;
}

.my-border-color(l, @c, @w) {
  border-left-color: @c;
  border-left-width: @w; 
}

.my-border-color(@one, @two) { // one two 随便写的名称, 可以换成别的
  width: 100px;
  height: 100px;
  color: @two;
}

.my-border-color(@one, @two, @three) {
  width: 200px;
  height: 200px;
}

.class {
  // 会命中  .my-border-color(all, @c) 和 .my-border-color(@one, @two)
  // 匹配 all 时,就会 red 传给 @c
  // 匹配 one two 时,就会将 red 传给 two
  .my-border-color(all, red); 
}

.classA {
  // 会命中  .my-border-color(l, @c, @w) ) 和 .my-border-color(@one, @two, @three)
  .my-border-color(l, red, 2px); 
}

// 编译为
.class {
  border-color: red;
  width: 100px;
  height: 100px;
  color: red;
}
.classA {
  border-left-color: red;
  border-left-width: 2px;
  width: 200px;
  height: 200px;
}

@arguments 和 @rest

@arguments 匹配所有参数

.my-mixin(@w, @s, @c) {
  border: @arguments;
  color: @c;
}

.class {
  .my-mixin(1px, solid, red)
}

// 编译为,会将 @arguments 替换为所有参数的组合
.class {
  border: 1px solid red;
  color: red;
}

@rest 匹配剩余参数

.my-mixin(@w, @rest...) {
  width: 100px;
  border: @rest;
}

.class {
  .my-mixin(100px, 1px, solid, red)
}

// 编译为
.class {
  width: 100px;
  border: 1px solid red;
}

嵌套

使用 & 在嵌套中代表父级,在做伪类和伪元素比较实用

.classA {
  width: 1000px;

  .classB {
    width: 800px;

    &:hover {
      color: red;
    }

    // 没有 & 会被编译为 .classA .classB :hover 不能真正选择到伪类
    // :hover {
    //   color: black
    // }
  }

  &:hover {
    color: green;
  }
}

// 编译为
.classA {
  width: 1000px;
}
.classA .classB {
  width: 800px;
}
.classA .classB:hover {
  color: red;
}
.classA:hover {
  color: green;
}

@规则(例如 @media@supports)可以与选择器以相同的方式进行嵌套。@规则会被放在前面(冒泡),同一规则集中的其它元素的相对顺序保持不变。

.component {
  width: 300px;
  @media (min-width: 768px) {
    width: 600px;
    @media  (min-resolution: 192dpi) {
      background-image: url('/img/retina2x.png');
    }
  }
  @media (min-width: 1280px) {
    width: 800px;
  }
}

// 编译为
.component {
  width: 300px;
}

@media (min-width: 768px) { // @media 冒泡到外面,width:600还是作用在.component上
  .component {
    width: 600px;
  }
}

@media (min-width: 768px) and (min-resolution: 192dpi) {
  .component {
    background-image: url(/img/retina2x.png);
  }
}

@media (min-width: 1280px) {
  .component {
    width: 800px;
  }
}

extend

使用 extend 可以将一整个规则集集成过来,需要与 & 一起使用,语法为 .a { &:extend(.b); }

.inline {
  color: red;
}

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

// 编译为
.inline,
nav ul {
  color: red;
}

nav ul {
  background: blue;
}