GX博客

分享个人 Full-Stack JavaScript 项目开发经验

Sass快速入门

网上已有不少 Sass 的快速入门教程,中文官网也有很详尽的介绍。本文旨在用简洁的语言,整理出 Sass 的主要功能,顺便带出一些注意问题。只要熟练这些的基本功能,便可在实际应用上作延申。

了解有关 Sass 编译环境的介绍,可以参阅:


下面说明例子均基于 Sass 的 SCSS 语法格式,CSS 语法在 SCSS 中通用。


嵌套

.container {
  p {
    color: #337ab7;
    // 1、允许属性嵌套,但不常用,一般使用 CSS 属性值的缩略写法。
    border: #666 {
      width: 1px;
      style: solid;
    }
  }

  // 2、编译时,& 会被替换成上一层的父选择器,它必须作为选择器的第一个字符!
  &-black {
    color: #333;
  }

  // 3、@media 最终会被编译到最外层。
  @media (max-width: 430px) {
    line-height: 32px;

    // 4、@at-root 指令可使规则跳出当前指令,或直接置于文档最外层。
    @at-root (without: media) {
      .warn {
        color: red;
      }
    }
  }
}

编译结果如下:

.container p {
  color: #337ab7;
  border: #666;
  border-width: 1px;
  border-style: solid;
}

.container-black {
  color: #333;
}

@media (max-width: 430px) {
  .container {
    line-height: 32px;
  }
}

.container .warn {
  color: red;
}

变量

// 1、$ 开头,赋值方式跟 CSS 属性写法一样
// 2、受块级作用域约束
// 3、先声明后使用
// 4、使用 !default 声明变量默认值时,如果变量先前没有被赋值,则此时被赋值为默认值

$var_name: 4em;
$var_name: 3em !default;

a {
  // 变量值后添加 !global 可把其提升为全局变量,谨慎使用,尽量统一定义
  $var_global: 2em !global;
  font-size: $var_name;
}

// 插值语句 #{}
// 使用情形:
// 1、在选择器或属性名中使用变量
// 2、给有引号的字符串插入动态值(被插入的那部分值将被编译为无引号字符串)
// 3、可以用来确保 / 不被当作除法运算

p {
  $prefix: "alert";
  $path: "../data/";

  .#{$prefix}-span {
    color: #333;
    background-image: url("#{$path}example.png");
  }
}

编译结果如下:

a {
  font-size: 4em;
}

p .alert-span {
  color: #333;
  background-image: url("../data/example.png");
}

对于 UI 框架项目中的变量,建议使用 _variables.scss 对组件元素值、色彩风格、页面布局标准值等进行统一定义。


运算

SassScript 支持的数据类型有:

  • 数值,如 8、.5、3em。
  • 字符串,包括带引号和不带引号。
  • 颜色,包括色值英文、十六进制色值、rgb、rgba、hsl、hsla。
  • 布尔型,true 和 false。
  • 空值,null。
  • 数组,用空格或逗号作分隔符的数组值。
  • maps,形如 (key1: value1, key2: value2)的对象。

运算符种类包括:算术运算符(+, -, *, /, %),关系运算符(<, >, <=, >=, ==, !=)。另外,字符串可以使用 + 连接,或者使用 #{} 插入值。

对于无意义的、单位不可相互转换的运算,sass 在编译时会报错而终止。


拓展的@import指令

以下情况下,@import 仅作为普通的 CSS 语句:

  • 文件拓展名是 .css;
  • 文件名以 http:// 开头;
  • 文件名是 url();
  • @import 包含媒体查询。

除以上情况,sass 会尝试找到 .scss 或 .sass 文件并导入(可省略扩展名)。

在 sass 中,@import 指令还可以同时导入多个文件,路径以逗号分隔;在 url() 方式中也可通过 #{} 使用变量;嵌套在其它选择器中。

最终,所有导入的文件会合并编译到同一个 CSS 文件中。若果不想被导入的文件被单独编译成一个 css,可以在文件名前添加 _ ,如 _header.scss,导入方式不变,即:

@import "header";

值得一提,@import 指令是构建 UI 框架时的模块化、组件化的基础。


@extend指令

延申指令可以在一个元素使用到另一个元素中的样式时,避免重复的编写。这可以很好地帮助我们处理通用样式特殊样式的关系。

多重延伸

即同一个选择器可以延申多个选择器。

.size {
  width: 10px;
}

.color {
  color: #333;
}

.btn {
  // 后面延申的样式享有更高优先级
  @extend .size;
  @extend .color;
}

继续延伸

即选择器的延申具有链式关系。

.btn {
  width: 100px;
  height: 28px;
}

.btn-normal {
  @extend .btn;
  padding: 10px;
}

.btn-alert {
  @extend .btn-normal;
  color: red;
}

占位符选择器

这可以使只在延申中使用的选择器不被编译到 css 文件中。

// btn 的样式不会被编译到 css 文件中
%btn {
  width: 10px;
  height: 10px;
}

.btn-alert {
  @extend %btn;
}

延申的注意问题

  • 选择器列(如 .a .b)不可以延申给其它元素。
  • 当遇到复杂的延申情况,Sass 只会编译出有用的选择器。我们应该避免使用这些难以预测的延申。
  • 在其它指令中(如 @media)使用 @extend 时,只能延伸给相同指令层中的选择器。
  • 连缀选择器(如 .a.b.c)可以被延申,但可能会因此而产生新的选择器,最终编译报错。可以为其添加 !optional 标记来避免生成新的选择器。

控制指令

sass 中用于流程控制的指令。

.container {

  $var: 1;

  // 1、条件控制
  @if $var > 1 {
    color: red;
  } @else if $var == 1 {
    color: blue;
  } @else {
    color: black;
  }

  // 2、循环控制
  @for $i from 0 through 3 {
    // [0, 3]
    .through-#{$i} {
      font-size: 12px + $i;
    }
  }
  @for $i from 0 to 3 {
    // [0, 3)
    .to-#{$i} {
      font-size: 12px + $i;
    }
  }
  $i: 0;
  @while $i < 3 {
    .while-#{$i} {
      font-size: 12px + $i;
    }
    // 注意控制循环初始值、终止条件和递增!
    $i: $i + 1;
  }

  // 3、遍历数组,支持一元和二元数组
  @each $color, $font-size in ((red 12px), (blue 13px)) {
    .p-#{$color} {
      color: $color;
      font-size: $font-size;
    }
  }

  // 4、遍历 maps
  @each $key, $value in (h1: 2em, h2: 1.5em) {
    #{$key} {
      font-size: $value;
    }
  }
}

混合指令

@mixin 指令用于定义可复用的一组样式。它可以接收参数,同样需要先定义后使用。

// 1、不接收参数的混合
@mixin clearfix {
  &:before,
  &:after {
    content: " ";
    display: table;
  }
  &:after {
    clear: both;
  }
}

// 2、接收参数的混合。注意,可选(带有默认值的)参数要求放在必须参数后面!
@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height: 36px, $border-radius: 3px) {
  padding: $padding-vertical $padding-horizontal;
  font-size: $font-size;
  line-height: $line-height;
  border-radius: $border-radius;
}

// 3、不确定参数数量的混合
@mixin button-border($border...) {
  border: $border;
}

// 4、类似于 React 组件合成方式的混合,混合内还包含其它选择器
@mixin p-compose {
  p {
    @content;
  }
}

// 调用方式
section {
  @include clearfix;

  .btn {
    @include button-size(5px, 5px, 12px);
    @include button-border(1px solid #ccc);
  }

  @include p-compose {
    a {
      color: #337ab7;
    }
  }
}

混合中变量的优先级同样遵循局部变量 > 全局变量的原则。

混合在架构上的良好实践是围绕组件实用样式进行划分,然后通过 _mixins.scss 统一导入:

sass/
├── mixins/
├     ├── _组件1.scss
├     ├── _组件2.scss
├     ├── ......
├     ├── _实用样式1.scss
├     ├── _实用样式2.scss
├     └── .....
└── _mixins.scss

函数指令

函数指令用于返回特定的运算结果,可在属性值和 SassScript 中调用,参数规则跟混合一样。

// 定义
@function btn-max-width($width, $padding) {
  @return $width - $padding*2;
}

// 调用
.btn {
  max-width: btn-max-width(100px, 10px);
}

了解更多官网教程,请点击这里

版权声明:

本文为博主原创文章,若需转载,须注明出处,添加原文链接。

https://leeguangxing.cn/blog_post_47.html