欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  web前端

SASS 之精华- @mixin、 @extend 和 Placeholder Selectors_html/css_WEB-ITnose

程序员文章站 2022-05-30 10:27:36
...
# 掌握 SASS 之精华—— @mixin、 @extend 和 Placeholder Selectors最近使用 Rails 折腾小项目,CSS 框架选用了 [Bourbon](https://github.com/thoughtbot/bourbon) 并结合了 [bitters](https://github.com/thoughtbot/bitters) 发现其能很好地利用了 SASS 特性。轻量级且定制性强,相比 bootstrap,Semantic-ui 这类啥都封装好的框架,轻量级多得多。在使用的过程中感叹在 Web 项目一开始的时候就得良好地组织好前端代码,不然地话,在模板文件中到处都是一堆 CSS ,后来者无力去改变也只能是继续堆砌 CSS,毫无阅读性以及组织结构规范,导致了大量的重复样式代码,CSS 复用性不高,作为一名代码癖的程序员,你还能忍受吗?还有一点就是开发者随便改动一个元素的class 或者 id 的样式,在没有良好组织样式代码的前提下很容易导致不可控的样式改变,等到线上更新了才他妈意识到这个class对另外一个元素的样式也改了。接下来看看一个使用了 bitters 组织的 Rails 项目样式代码的组织。- stylesheets  - base    - extends      - _button.scss      - _clearfix.scss    - mixins      - _flash.scss    - _bases.scss    - _buttons.scss    - _forms    - _lists.scss    - ...    - _variables.scss  - _account.scss  - _users.scss  - ...  - application.css.scss看到这样的目录结构,有没有很 SASS 味?  _bases.scss 文件中 **@import** 了 base 目录下包含了整个样式公共的一些文件,也许你也看到了 **extends** 和 **mixins** 子目录,别着急先上饭前菜,这篇文章重要就是要说明它们。_variables.scss 内容只要是颜色值、链接样式、字体样式等一些变量,例如```$black: #000000;```极其方便地被引用和复用。base 文件夹下的其他文件都是各种 HTML 元素的样式,有人说,你用 Semantic-ui 多方便啊,为啥这么折腾,哈,这不是我们今天讨论的内容;然后就是base 文件夹以外的一些样式文件都是按照其业务逻辑来组织,各个样式文件各司其职多好!  ##### ~~以上就是饭前菜,同是我也是分割线,请忽略,下面的内容才是重点~~  ### 关于 Mixin在 SASS 的世界里 ```mixin``` 是一种指令。它可以像函数一样把多个样式组织成为“一块”方便引用及复用,当然这个函数也是可以传递参数的。举个栗子:```@mixin center() {  display: block;  margin-left: auto;  margin-right: auto;}.container {  @include center();  /* Other styles here... */}/* Other styles... */.image-cover {  @include center;}```> center 没有参数,你可以省略括号,但还是最好不要省哈。通过 mixin ,在需要居中的元素上没必要都重复写三行代码,仅仅是简单地 ```@include``` 就好了,可方便简单了。  还可以传参呢?再看个栗子。```@mixin size($width, $height: $width) {  width: $width;  height: $height;}```要在其他元素上引用这样的大小样式:```.icon {  @include size(32px);}.cover {  @include size(100%, 10em);}```### 关于 Placeholder在 SASS 的世界里,Placeholder 也是一种特别的元素选择器,没错,就是类似 class 或者 id ,但有其特别之处。 placeholder 用 **%** 百分号表示。作为一种元素选择器,意味着能够被 SASS 中的 **@extend** 指令引用。先看栗子```%center {  display: block;  margin-left: auto;  margin-right: auto;}```细心的你一眼就看出这个栗子和上文的 mixin 没多大的区别,就是把 ```@mixin``` 替换为 ```%```而已,那么它们有啥区别呢,别急等会讲。此时你只记住这句话就好了:**在没有使用之前,placeholder编译不会CSS代码**。  在使用 placeholder 之前,我们简单介绍一下 ```@extend``` :该指令用于从 CSS 选择器以及 placeholder 这个特殊的选择器继承样式属性。那么使用 placeholder 就是这样:```.container {  @extend %center;}```### 选用 mixin 还是 placeholder上文抛出了 mixin 和 placeholder 有什么区别的问题,那么我们应该用哪种呢?是时候给出答案了。  使用 mixin 还是 placeholder 取决于使用上下文。具体一点就是:如果是需要传参数,建议使用 mixin ,否则使用 placeholder ,给出两个理由:1. placeholder 不支持传参啊。2. sass 编译之后,使用的 mixin 会生成大量重复代码,导致最后的样式文件体积变大。而 placeholder避免了生成重复代码。请看两者编译后的对比栗子。    ```    @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;  }  ```  ```  %center {    display: block;    margin-left: auto;    margin-right: auto;  }  .container {    @extend %center;  }  .image-cover {    @extend %center;  }  ```  编译后  ```  .container, .image-cover {    display: block;    margin-left: auto;    margin-right: auto;  }  ```看出来了吧,看不出来我也不解释了,哼。  来,看一下 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) }```我们可以看出 a,b 都想内容居中,但是颜色和大小需要自定义。充分地体现了 **传参就用mixin,其他的用 placeholder 的思想**,编译之后产生的CSS如下:```a, b {  margin-left: auto;  margin-right: auto;  display: block;}a {  background: pink;  height: 10em;}b {  background: blue;  height: 90px;}```### 关于 @extend还没写完参考链接:  [Sass: Mixin or Placeholder?](http://www.sitepoint.com/sass-mixin-placeholder/)  [What Nobody Told You About Sass’s @extend](http://www.sitepoint.com/sass-extend-nobody-told-you/)  [Why You Should Avoid Sass @extend](http://www.sitepoint.com/avoid-sass-extend/)