Less(v3.9.0)使用详解—mixin(混入)

3,741 阅读4分钟

该系列:

Less(v3.9.0)使用详解——基本使用

Less(v3.9.0)使用详解——变量

Less(v3.9.0)使用详解——嵌套和父选择器&

Less(v3.9.0)使用详解——extend(嵌套)

Less(v3.9.0)使用详解——mixin(混入)

其他待更新...

Mixins

混入样式

.a, #b {
  color: red;
}
.mixin-class {
  .a();
}
.mixin-id {
  #b();
}

编译为

.a, #b {
  color: red;
}
.mixin-class {
  color: red;
}
.mixin-id {
  color: red;
}

如果你不想mixins样式出现在编译结果中,加上()

.my-mixin {
  color: black;
}
.my-other-mixin() {
  background: white;
}
.class {
  .my-mixin();
  .my-other-mixin();
}

编译为

.my-mixin {
  color: black;
}
.class {
  color: black;
  background: white;
}

mixin里面能包含选择器

.my-hover-mixin() {
  &:hover {
    border: 1px solid red;
  }
}
button {
  .my-hover-mixin();
}

编译为

button:hover {
  border: 1px solid red;
}

Namespaces

可以把多个混入样式堆叠平放一起,然后用个命名空间包裹

#outer() {
  .inner {
    color: red;
  }
}

.c {
  #outer > .inner();
}

使用方式有下面几种

// all do the same thing
#outer > .inner();
#outer .inner();
#outer.inner();

对mixin命名空间可以减少与其他库mixin或用户mixin的冲突,它也可以成为“组织”mixin组的一种方式。

#my-library {
  .my-mixin() {
    color: black;
  }
}
// which can be used like this
.class {
  #my-library.my-mixin();
}

守卫

#namespace when (@mode = huge) {
  .mixin() { /* */ }
}

#namespace {
  .mixin() when (@mode = huge) { /* */ }
}

如果@mode = hug 为false,则mixin不会生效,以上两个编译后是一样的

#sp_1 when (default()) {
  #sp_2 when (default()) {
    .mixin() when not(default()) { /* */ }
  }
}

defalut()为假值

!important

mixin后添加该关键字会给mixin里的所有添加该关键字

.foo (@bg: #f5f5f5, @color: #900) {
  background: @bg;
  color: @color;
}
.unimportant {
  .foo();
}
.important {
  .foo() !important;
}

编译为

.unimportant {
  background: #f5f5f5;
  color: #900;
}
.important {
  background: #f5f5f5 !important;
  color: #900 !important;
}

带参数的mixin

.border-radius(@radius) {
  -webkit-border-radius: @radius;
     -moz-border-radius: @radius;
          border-radius: @radius;
}
#header {
  .border-radius(4px);
}
.button {
  .border-radius(6px);
}

可以设置默认值

.border-radius(@radius: 5px) {
  -webkit-border-radius: @radius;
     -moz-border-radius: @radius;
          border-radius: @radius;
}

多个参数用,或者;隔开,推荐;

使用逗号作为mixin分隔符使得不可能创建逗号分隔的css列表作为参数。

另一方面,如果编译器在mixin调用或声明中看到至少一个分号,则它假定参数由分号分隔,所有逗号都属于css列表

  • 两个参数,每个参数包含逗号分隔的列表 .name(1, 2, 3; something, else)
  • 三个参数,每个参数包含一个数字 .name(1, 2, 3)
  • 使用伪分号创建mixin调用,其参数包含逗号分隔的css列表 .name(1, 2, 3;)
  • 逗号分隔的默认值 .name(@param1: red, blue;)

可以定义具有相同名称和不同和参数数量的混合,会编译所有能编译成功的mixin

.mixin(@color) {
  color-1: @color;
}
.mixin(@color; @padding: 2) {
  color-2: @color;
  padding-2: @padding;
}
.mixin(@color; @padding; @margin: 2) {
  color-3: @color;
  padding-3: @padding;
  margin: @margin @margin @margin @margin;
}
.some .selector div {
  .mixin(#008000);
}

第二个mixin padding 没有默认值,所以编译失败,此时编译为

.some .selector div {
  color-1: #008000;
  color-2: #008000;
  padding-2: 2;
}

具名参数

mixin引用可以通过它们的名称提供参数值,而不仅仅是位置。任何参数都可以通过其名称引用,并且它们不必以任何特殊的顺序出现

.mixin(@color: black; @margin: 10px; @padding: 20px) {
  color: @color;
  margin: @margin;
  padding: @padding;
}
.class1 {
  .mixin(@margin: 20px; @color: #33acfe);
}
.class2 {
  .mixin(#efca44; @padding: 40px);
}

编译为

.class1 {
  color: #33acfe;
  margin: 20px;
  padding: 20px;
}
.class2 {
  color: #efca44;
  margin: 10px;
  padding: 40px;
}

@arguments 变量

@arguments表示传进来的所有参数

.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {
  -webkit-box-shadow: @arguments;
     -moz-box-shadow: @arguments;
          box-shadow: @arguments;
}
.big-block {
  .box-shadow(2px; 5px);
}

编译为

.big-block {
  -webkit-box-shadow: 2px 5px 1px #000;
     -moz-box-shadow: 2px 5px 1px #000;
          box-shadow: 2px 5px 1px #000;
}

高级参数和rest变量

如果您想要mixin接受可变数量的参数,使用...或者@rest

.mixin(...) {        // matches 0-N arguments
.mixin() {           // matches exactly 0 arguments
.mixin(@a: 1) {      // matches 0-1 arguments
.mixin(@a: 1; ...) { // matches 0-N arguments
.mixin(@a; ...) {    // matches 1-N arguments
.mixin(@a; @rest...) {
   // @rest is bound to arguments after @a
   // @arguments is bound to all arguments
}

模式匹配

有时,您可能希望根据传递给mixin的参数来更改它的行为。

.mixin(dark; @color) {
  color: darken(@color, 10%);
}
.mixin(light; @color) {
  color: lighten(@color, 10%);
}
.mixin(@_; @color) {
  display: block;
}

如果我们这么用

@switch: light;

.class {
  .mixin(@switch; #888);
}

编译为

.class {
  color: #a2a2a2;
  display: block;
}

使用mixin作为函数

.average(@x, @y) {
  @result: ((@x + @y) / 2);
}

div {
  // call a mixin and look up its "@result" value
  padding: .average(16px, 50px)[@result];
}

编译为

div {
  padding: 33px;
}

能够被重写

// library.less
#library() {
  .mixin() {
    prop: foo;
  }
}

// customize.less
@import "library";
#library() {
  .mixin() {
    prop: bar;
  }
}

.box {
  my-value: #library.mixin[prop];
}

编译为

.box {
  my-value: bar;
}

如果不指定具体返回字段,则以最后一个字段为准

.average(@x, @y) {
  @result: ((@x + @y) / 2);
}

div {
  // call a mixin and look up its final value
  padding: .average(16px, 50px)[];
}

编译为

div {
  padding: 33px;
}

递归mixin

.generate-columns(4);

.generate-columns(@n, @i: 1) when (@i =< @n) {
  .column-@{i} {
    width: (@i * 100% / @n);
  }
  .generate-columns(@n, (@i + 1));
}

编译为

.column-1 {
  width: 25%;
}
.column-2 {
  width: 50%;
}
.column-3 {
  width: 75%;
}
.column-4 {
  width: 100%;
}

mixin守卫

.mixin(@a) when (lightness(@a) >= 50%) {
  background-color: black;
}
.mixin(@a) when (lightness(@a) < 50%) {
  background-color: white;
}
.mixin(@a) {
  color: @a;
}
.class1 { .mixin(#ddd) }
.class2 { .mixin(#555) }

编译为

.class1 {
  background-color: black;
  color: #ddd;
}
.class2 {
  background-color: white;
  color: #555;
}