4

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

一年半之前,我开始使用Sass的时候,对于include a mixinextending a placeholder的区别,我花费了一些时间去理解它们。
在那个时候,单单placeholder的概念,就已经相当于一种黑魔法巫术一样让我不知其解。

如果你有同样的疑问,不要担心,我接下来会说解释指明它们之间的区别。今天我们会学到minxin是什么东西,和什么时候去使用Sass的placeholder。你会明白他们有不同的用处,不能混淆使用。

提醒:我接下来要谈论的关于Sass的观点,同样适用于其他CSS预处理器,不管是Stylus,Less,还是其他的。技术大多做的是同样的事情,所以完全不用担心这篇文章的内容,是否适合你已经选择使用的其他CSS预编译工具。

首先我们先去熟悉和认识 Sass placeholders and mixins

Mixin it up, 混合体,封装体

一个mixin指令可以让你去定义很多CSS规则。把它看做是一个function函数,方法,这个function可以有自己的参数。它会输出这些css规则内容,而不是返回一个值。下边是来自Sass官方参考里定义:

Mixins 允许自己定义样式,这些样式可以在全局样式表里重用,而不用去借助一些无语义的类,比如.float-left。Mixins可以包含完整的CSS样式规则和其他Sass中的特性规则等。mixin还可以接收参数,不同的参数值将产生不同的样式规则。

在样式表中,你会见到一些CSS规则声明被重复出现了好多次。你明白这样的代码不好,而且还知道DRY(Don't Repeat yourself)这个概念原则。现在使用mixin去改善这样的代码:

@mixin center() {
  display: block;
  margin-left: auto;
  margin-right: auto;
}
 
.container {
  @include center();
  /* Other styles here... */
}
 
/* Other styles... */
 
.image-cover {
  @include center;
}
提醒:include使用的时候,如果你不传递参数给mixin,那么可以去掉mixin名字后边的括号。比如 @include center; 其实你也可以在mixin定义的时候就把括号去掉。比如 @mixin center {}

定义了这个mixin之后,你就不用每次去重复那三行元素居中的规则。使用的时候,就去包含这个mixin。

在某些情况下,可以使用一个mixin去创建一些属性组合的“缩写”。例如 widthheight。你应该已经厌倦了重复书写这两行属性。特别是当这两个属性值一样的时候。现在我们就使用一个mixin来解决这些问题!

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

很简单吧。这里我们设置hight属性的默认值和width参数的值一样。当你想定义一个元素的面积大小时,你可以这样做:

.icon {
  @include size(32px);
}
 
.cover {
  @include size(100%, 10em);
}
提醒:当我想去设置一个元素的position属性时,为了避免逐个书写top, right, bottom, left这些属性。也可以去使用mixin这种很好的语法糖。

认识 Placeholder(占位符)

Placeholders 是一种奇怪的东西。它们是class,但是在Sass编译过后,并不会被输出,出现在样式表文件里。然后你会问它有什么意义。事实上,如果不是为了@extend这个指令,它都没什么意义。你可以这样去写一个placeholder:

%center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}
提醒:Like a placholder, a mixin is likewise useless unless its referenced, so this section is not necessarily saying they are different in that respect, but this is only clarifying that even though it looks similar to a CSS declaration block, it won’t get compiled on its own.

placeholder的写法使用%,而不是.(点),但是遵守class的命名规则。

如果编译Sass文件,placeholder的代码不会出现在生成的css的文件里。正如我说过的,placeholder的代码不会被编译出现在css源文件里。

placeholder 要通过 @extend 去使用。@extend指令的作用是继承一个CSS选择器的属性或者一个Sass的placeholder代码。例如:

.container {
  @extend %center;
}

这样之后,Sass会获得%center这个placeholder的内容给.container 这个类。

另外,你还可以extend一个CSS class,就像这样:

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

这是@extend的常用法。当你使用模块组件化开发一个网站或者应用,继承选择器是便利的。

使用哪一个

我们应该使用哪一个,mixin还是placeholder。要看具体使用场景。
最好的建议是:如果你需要参数变量,使用mixin。否则,继承一个placehodler。这样做两个原因:

第一,在placeholder里面,不能像mixin那样传递使用参数变量。但是可以使用全局变量。

第二,当你使用mixin时,Sass会重复输出这个mixin的属性规则内容,不会让CSS选择器公用这个mixin。这样的话,样式表将会变得很大。

@mixin center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}
 
.container {
  @include center;
}
 
.image-cover {
  @include center;
}

输出如下:

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

看到重复的CSS了吧。如果只有三行代码重复的话,感觉好像问题还不是很糟糕。但是如果这个mixin有300行呢。重复的代码就太多了。那让我们使用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;
}

看起来好多了吧。这样就避免了总是重复相同的属性规则,使用placeholder,会让整个样式表文件很瘦。

另外,如果你在不同的地方都要使用一些属性,但是这些属性的值是变量决定的,那么mixin是一个好的选择。如果你的CSS属性同时有固定的和变动的值,那么你可以组合使用mixin和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, 生成了干净不重复的CSS:

a, b {
  margin-left: auto;
  margin-right: auto;
  display: block;
}
 
a {
  background: pink;
  height: 10em;
}
 
b {
  background: blue;
  height: 90px;
}

总结

希望你已经清楚了什么是mixins和placeholders,而且知道什么时候去使用它们和它们编译之后的效果。

图片描述


前端知否
714 声望49 粉丝

to be is to do


引用和评论

0 条评论