专栏首页前端知否Sass->什么时候使用Mixins 和 Placeholders

Sass->什么时候使用Mixins 和 Placeholders

原文: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名字后边的括号。比如 @includecenter; 其实你也可以在mixin定义的时候就把括号去掉。比如 @mixincenter{}

定义了这个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,而且知道什么时候去使用它们和它们编译之后的效果。

本文分享自微信公众号 - 前端知否(qianduanzhifou),作者:QETHAN

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Vue.js中的延迟加载和代码拆分

    虽然现在网络环境和电子设备变得越来越好,但是保持应用程序快速加载变得越来越困难。在本系列中,我将深入研究我们在实践中使用的Vue性能优化技术,并且您可以在Vue...

    前端知否
  • JSON.stringify方法的5个秘密功能

    JSON.stringify()方法将JavaScript对象或值转换为JSON字符串。

    前端知否
  • ES6+好用的小技巧,让你的代码更干净,短巧,易读

    前端知否
  • 如何高效利用 Grafana 监控分析 TiDB 指标

    使用 TiDB Ansible 部署 TiDB 集群,会同时部署一套 Grafana + Prometheus 的监控平台,这套监控用来收集和展示 TiDB 集...

    PingCAP
  • 容器超融合的实现&持久存储的动态分配 : Openshift3.9学习系列第六终结篇

    干货巨献:Openshift3.9的网络管理大全.加长篇---Openshift3.9学习系列第二篇

    魏新宇
  • 集成测试是什么?为什么要做集成测试

    集成测试,也叫组装测试或联合测试。在单元测试的基础上,将所有模块按照设计要求(如根据结构图)组装成为子系统或系统,进行集成测试。

    测试小兵
  • Django快速入门

    Django 是用 Python 写的一个自由和开放源码 web 应用程序框架。 web框架是一套组件,能帮助你更快、更容易地开发web站点。当你开始构建一个w...

    用户1432189
  • 分布式事务之解决方案(最大努力通知)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    海仔
  • 启动tomcat服务器报错:ERROR ContextLoader:307 - Context initialization failed

      项目环境是Eclipse企业版4.7.2 + jdk1.8.0_161 + apache-tomcat-8.5.30

    黑泽君
  • C++ OpenCV特征提取之BFMatcher匹配

    Brute Force匹配是opencv二维特征点匹配常见的办法,BFMatcher总是尝试所有可能的匹配,从而使得它总能够找到最佳匹配,这也是Brute Fo...

    Vaccae

扫码关注云+社区

领取腾讯云代金券