Sass:Mixin还是Placeholder

编辑推荐: 掘金是一个高质量的技术社区,从 CSS 到 Vue.js,性能优化到开源类库,让你不错过前端开发的每一个技术干货。 点击链接查看最新前端内容,或到各大应用市场搜索「 掘金」下载APP,技术干货尽在掌握中。

本文由大漠根据Hugo Giraudel的《Sass: Mixin or Placeholder?》所译,整个译文带有我们自己的理解与思想,如果译得不好或不对之处,还请同行朋友指点。如需转载此译文,需注明英文出处:http://www.sitepoint.com/sass-mixin-placeholder/,以及作者相关信息。

——作者:Hugo Giraudel

——译者:大漠

在大约一年半年前使用Sass的时候,有一件事让我花了很长的时间,那就是如何区别Sass的@mixin%placeholder。实际上,%placeholder。在当时的情况这之下,就算是概念对我来说都是黑色地带。

如果你也碰到类似的情况,不用担心,因为我会尽量的引导你。今天我们就来探究,什么时候是@include定义好的@mixin,什么时候是@extend定义好的%placeholder。你就会明白它们服务的目的是不一样的,不能混为一谈。

注:虽然我们今天讨论的是Sass,但这篇文章也适合于其他的CSS预处理器语言。无论是Stylus、LESS,还是你正在使用的Sass。该技术通常做的是同样的事情,这篇文章介绍的内容都适合你选择的工具。

接下来我们要做的就是讨论,何时使用Sass的@mixin%placeholder

Mixin至上

@mixin是一个指令,他可以根据参数个数定义多个规则。可以把它看成是CSS的内容存储起来,而不是返回的函数的值。Sass的官方是这样定义的@mixin:

Mixins allow you to define styles that can be re-used throughout the stylesheet without needing to resort to non-semantic classes like .float-left. Mixins can also contain full CSS rules, and anything else allowed elsewhere in a Sass document. They can even take arguments which allows you to produce a wide variety of styles with very few mixins.

@mixin可以定义样式,不需要借用任何类名,比如说.float-left用于整个样式表中。@mixin也可以定义所有CSS规则,用于Sass文档的任何地方。甚至还可以给@mixin定义参数,用极少的@mixin生产更多的样式。

我们已经介绍了他的术语。我可以说,你会经常发现在你的样式文件中常常会有一些相同的样式重复多次出现。你也知道,代码重复不是好事,你熟悉DRY(不想重复)的概念。要想修正这一点,你只需要给这些重复的样式声明定义一个Mixin

@mixin center() {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.container {
  @include center();
  /* 其他的样式... */
}

/* 其他的样式... */

.image-cover {
  @include center;
}

注:如果没有给@mixin传递任何参数,你可以省略后面的()。甚至你在定义@mixin的时候就可以忽略它。

有了这个@mixin center之后,你每次让一个元素居中时,就不需要重复的去写那三行代码,你只需要使用@include将定义的@mixin center引入进去。这样是不是很方便呀!

有时候你会想创建一个@mixin,用来速记一些成对的属性。例如widthheight。你一遍又一遍输入这两个属性,难道不累吗?特别是当两个属性的值相同的时候。那么我们来定义一个@mixin来处理这个现象:

@mixin size($width, $height: $width) {
  width: $width;
  height: $height;
}

非常简单,不是吗?注意,我们在定义了两个参数,而且使用$height参数的值默认情况之下和$width具有相同的值。现在,如果你要给一个元素定义尺寸,你只需要像下面这样做:

.icon {
  @include size(32px);
}

.cover {
  @include size(100%, 10em);
}

注:另外一个很优秀的@mixin实例。每次想让一个static元素重新定位时,我可以避免每次书写top,right,bottom,leftposition属性。

了解Placeholder

%placeholder非常的怪异,在SCSS编译的时候,他是自身是不会输出代码的。此时你或许会问,那这个有什么意义呢?其实不然,这种情形只会发生在没有使用@extend调用你定义的%placeholder。当然这事情一码是一码,我们先来看看如何定义一个%placeholder:

%center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

编者按:%placeholder一样,如果@mixin不被@include调用,同样是不会编译出代码的。所以这部分并不能说明他们的不同之处,只是向大家澄清。即使他看起来像一个CSS代码块,但只有调用的时候才会编译出CSS样式代码。

基本上,你把它写成类似一个类名,不同之处是把代表类名的.符号换成了代表placeholder%符号。此外,他遵循类同样的命名规则

现在,如果你想编译你的SCSS,在此例中,你看不到编译出来的文件中有这些代码。正如我所说的:%placholder不会被编译到CSS样式文件中。

所以到目前为止,这个%placeholder是没有任何作用。你也不能使用他,除非你通过@extend调用了。你可以在一个CSS选择器或者SCSS的%placeholder中通过@extend调用定义好的%placeholder。正如下面所演示的一样:

.container {
  @extend %center;
}

这一来,Sass会在容器.container调用定义好的%center。(即使你不知道其中的为什么也并不重要,因为我们这样做就行了)。正如我所说的,你也可以在CSS的选择器中(除了SCSS的%placeholder),也可以@extend定义好的CSS类,如下所示:

.table-zebra {
  @extend .table;

  tr:nth-of-type(even) {
    background: rgba(0,0,0,.5);
  }
}

这是一个非常常见的@extend用例。在这个示例中,在.table-zebra类中调用了.table类,因为table.table-zebra具有table.table一些相同的样式,然后在.table-zebra中添加了修饰这个表样的特殊样式规则。在开发网站或应用程序的模块组件时,通过@extend来调用定义好的类选择器是非常有用的。

使用哪个呢?

现在的问题是,我们应该使用哪个呢?好吧,在我们领域的一切,依靠的是:依赖。依赖于上下文和你最终要怎么做。

最好的建议是:如果你需要使用变量,最好使用@mixin,否则使用%placeholder。主要有两个原因:

  • 首先,你不能在一个%placeholder中使用变量。其实可以,但你不能将变量传递到%placeholder中,所以你不能像@mixin一样根据上下文生成特定的CSS。
  • 第二,当不根据上下文传入变量时,在Sass中使用@mixin,会使用它们变得更为复杂。简单的说,在Sass中每次重复复制@mixin,那他的输出,不仅会造成重复的CSS代码,还会让你的样式文件越来越庞大。

重新回到本文中的第一个示例:

@mixin center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.container {
  @include center;
}

.image-cover {
  @include center;
}

上面SCSS代码编译出来的CSS代码如下:

.container {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.image-cover {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

请注意,重复的CSS出来了。如果只有三行重复,这并没有什么危害,但是如果你的@mixin不只三行代码,或者在你的项目中重复十几次调用定义的@mixin,那么重复的代码有可能就会变成三百行。如果我们使用%placeholder来改造这个示例呢?

%center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.container {
  @extend %center;
}

.image-cover {
  @extend %center;
}

编译出来的CSS代码:

.container, .image-cover {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

好多了,编译出来的代码,采用群组选择器将重复的代码合并在一起。所以当你知道一些样式永久不变,而且会重复出现多次的时候,你就可以使用@extend扩展一个定义好的%placeholder。这样可以避免Sass生成重复的代码,让你的样式表更简洁。

另一方面,如果你愿意在相同的样式基础上具有不同的样式(比如size,color),那么使用@mixin是最好的方法。如果你有一个组件,其中有固定的样式,也有动态的样式,那么@minxin%placeholder将是最佳选择。

%center {
  margin-left: auto;
  margin-right: auto;
  display: block;
}

@mixin skin($color, $size) {
  @extend %center;
  background: $color;
  height: $size;
}

a { @include skin(pink, 10em) }
b { @include skin(blue, 90px) }

在这种情况这下,在@mixin中扩展了设置固定样式的%placeholder,而不是直接在里面通过@extend来扩展%placeholder,这样可以让你的样式更简洁:

a, b {
  margin-left: auto;
  margin-right: auto;
  display: block;
}

a {
  background: pink;
  height: 10em;
}

b {
  background: blue;
  height: 90px;
}

结论

通过这篇教程,我希望你不仅清楚@mixin%placeholder,而且还应该知道什么时候用什么,他对编译出来的CSS会有什么影响。

如果你有关于Sass功能有什么不同的体验和经验,欢迎在评论中与我们一起分享。

译者手语:整个翻译依照原文线路进行,并在翻译过程略加了个人对技术的理解。如果翻译有不对之处,还烦请同行朋友指点。谢谢!

如需转载烦请注明出处:

英文原文:http://www.sitepoint.com/sass-mixin-placeholder/

中文译文:http://www.w3cplus.com/preprocessor/sass-mixin-placeholder.html

返回顶部