[译文] 如何在 CSS 预处理器 Less 中使用 Mixins

2,234 阅读5分钟

原文地址: A Comprehensive Introduction to Less: Mixins

什么是 Mix

在 Less 中, 我们可以定义一种叫 “mixins” 的东西 —— 和编程语言中的函数有一点的相似。 在 Less 中, 它被用来灵活的组件化 CSS 中可重复使用的 class。 Mixin 允许你把一个 class 的所有属性嵌入到另外的一个 class 中 —— 就像它的一个属性一样, 仅仅通过简单的 include class 的名字。 它仅仅是一个变量,但是拥有一个 class 的属性。 任何的 CSS class 和 id 规则都可以混在里面。

.round-borders {
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
}

#menu {
  color: gray;
  .round-borders;
}

// 输出
.round-borders {
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
}

#menu {
  color: gray;
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
}

正如你所看见的一样, 这个输出包含了 mixin 自己和整个 CSS 规则集。 如果你不想 mixins 出现在你编译之后的 .css 文件中,你仅仅需要在 mixin 的名字后面添加空的括号。 你可能想知道为什么我在 mixin 的名字中使用大写字母。 这是因为 CSS 选择器也可以使用点符号, 所以没有办法区分是不是来自于一个 mixin。 这也正是我使用大写字母的原因, 同样的在面对对象编程中, 我们经过对 class 使用大写字母。

请带好你的参数

Mixins 可以携带参数,这就意味着它可以通过携带参数来提高他们的效率。 携带参数的 mixin 在编译的时候不会输出本身。它的属性将输出在调用它的模块中。典型的例子是创建一个在多个浏览器中都能使用的圆角 mixin

.round-borders (@radius) {
  border-radius: @radius;
  -moz-border-radius: @radius;
  -webkit-border-radius: @radius;
}

下面展示了我们如何使它 :

header {
  .round-borders(4px);
}

.button {
  .round-borders(6px);
}

携带参数的 mixins 也可以拥有默认的参数:

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

现在我们可以这样引用它:

header {
  .round-borders;
}

它将会引入一个 5px 的 border-radius

如果你要用一个没有任何参数的 mixin, 并且你不 想让他输出在编译后的文件中,就给他一个空的参数吧,像下面这样:

.hiddenMixin() {
  color: black;
}
p {
  .hiddenMixin()
}

将会输出这样的结果:

p {
  color: black;
}

mixin 中有 @arguments 这样一个特殊的变量, 它包含着所有传给这个 mixin 的参数(如果没有传递参数就使用申明的默认参数)。 该参数的值是所有参数的值中间用空格分开构成的。 使用 @argument 是一个有用的快速分配所有参数的技巧。

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

.box-shadow(2px, 5px);

输出结果将是这样:

box-shadow: 2px 5px 1px #000;
-moz-box-shadow: 2px 5px 1px #000;
-webkit-box-shadow: 2px 5px 1px #000;

一个小小的配对:)

如果你在同一个作用域中有多个相同名字的 mixin, 将会检查它们的参数是否匹配。

最简单的例子就是匹配参数个数不同的 mixin。 只有那个参数个数相同的 mixin 才会被匹配, 这儿也有一个例外: 参数个数为 0 的 mixin 总是会被使用。

下面就是一个简单的例子:

.mixin() { // this is always included
  background-color: white;
}

.mixin(@a)  {
  color: @a;
}

.mixin(@a, @b) {
  color: fade(@a, @b);
}

现在我们可以用一个单一参数来调用 .mixin。我们将会得到第一个定义的输出,但是如果我们用两个参数来调用 .mixin,那么我们将会得到第二个定义的输出: @a@b 的淡入。

另外一种控制 mixin 匹配的方式是在申明 mixin 的时候指定一个词:

.mixin (dark, @color) {
  color: darken(@color, 10%);
}

.mixin (light, @color) {
  color: lighten(@color, 10%);
}

.mixin (@_, @color) { // this is always included
  display: block;
}

@switch: light;

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

我们将得到下面的输出:

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

上面的例子中通过 mixin 传递出来的颜色的 lighted 的。 如果 @switvh 的值是 dark, 其结果将会是 dark。 只有被匹配到的 mixin 定义才会被使用。变量可以去匹配任意值, and anything other than a variable matches only with a value equal to itself.

守卫

另外一种制约多个 mixin 同时使用的方法是使用 guards。它是一个特殊的表达式,和 mixin 的申明联合起来使用。 他必须在 mixin 使用之前是真实的。 当你想匹配表达式的时候,使用 gurads 往往是有用的。

在开始使用 guards 的时候, 我们是从 when 这个关键词开始的:

.mixin (@a) when (lightness(@a) >= 50%) {   
  background-color: black;
}

.mixin (@a) when (lightness(@a) < 50%) {
  background-color: white;
}

.mixin (@a) { // this is always included
  color: @a;
}

.class1 {
  .mixin(#ddd);
} // this matches the first mixin

.class2 {
  .mixin(#555);
} // this matches the second mixin

我们将会得到这样的结果:

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

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

在 guards 中支持的操作符有 >, >=, =, 等

既然我们如此对 TA 执迷, 那么如何去追寻更好的 TA ?

这儿有一些小小的奖励给你。 他是一些和 Less 有关资源的一些列表, 你可以按照你的意愿在你的项目中去使用它们。 同时,这里也有一些使用 mixins 和变量的小项目供你参考

如果你想找更多的关于 Less 的资源, GitHub 是一个正确的去处。和你所看见的一样,这里有很多和 Less 相关的好东西,还在等什么?快去看一看吧。

结束语

事实上, Less 是一种快速简单现代化书写 css 的方式。 因此我们不必太过于保守, 我们需要去尝试使用它。 在 Less 上稍微花一点时间你就能更加快速高效的创造出更加复杂的样式。 预祝你 coding 愉快,一直记得有 Less 的陪伴 :)

捐赠

写文不易,赠我一杯咖啡增强一下感情可好?

alipay