Sass中的样式复用方法详解

6/6/2021 CSS

在团队开发中,复用代码能减少冗余,抹平编写风格的差异。或者在编写同主题的组件,统一文字,颜色,间隔等样式,复用样式代码是必不可少的。

Sass 提供了多种方法来实现样式的复用,包括 @import@extend@media@mixin 等。本文将详细介绍这些方法的用法和应用场景。

# @import

Sass @import跟原生 css 的@import类似,都是导入其他文件。如果 Sass @import的以下类型,Sass 编译器就直接转换成原生,而不导入 Sass 文件。

@import 'foo.css';
@import 'foo' screen;
@import 'http://foo.com/bar';
@import url(foo);

如果省略后缀,Sass 会自动寻找对应的 Sass 文件并导入到文件中。

一般 Sass 都是配合下方的复用方法去使用,要复用其他文件的一些样式,记得先@import进来。

# @extend

当需要复用通用样式的时候,就会用到这个@extends的语句。例如有一个通用button样式,和一个特殊button样式,那么 Sass 就会把关于.button的样式也会应用在.submit-button中。

// 通用样式
.button {
  color: #ffffff;
  background-color: blue;
}

.button.hasError {
  background-color: red;
}

// 特殊样式
.submit-button {
  @extend .button;
  color: #07a123;
}

// 将会编译成

.button,
.submit-button {
  color: #ffffff;
  background-color: blue;
}

.button.hasError,
.submit-button {
  background-color: red;
}

.submit-button {
  color: #07a123;
}

如果是@extends多个,那么跟 css 的规则一样,写在末尾的优先级会更高一点。

当然@extends自己也是可以进行延伸的。

官方的例子:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}
.criticalError {
  @extend .seriousError;
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%;
}

// 编译成:
.error,
.seriousError,
.criticalError {
  border: 1px #f00;
  background-color: #fdd;
}

.seriousError,
.criticalError {
  border-width: 3px;
}

.criticalError {
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%;
}

以上是@extends 最常用的方式。

# @media

Sass 中的@media与 Css 用法是一样的,但它帮我们拓展部分功能。

  1. css 规则中嵌套
  2. 使用变量

在 css 规则中,media 要写在最外层,而 Sass 提供让我们写在内层,并提供嵌套的方式。

.button {
  width: 100px;
  @media screen and (min-width: 900px) {
    width: 200px;
  }
}

// 编译成
.button {
  width: 100px;
}

@media screen and (min-width: 900px) {
  .button {
    width: 200px;
  }
}

@media screen {
  .button {
    @media (min-width: 900px) {
      width: 200px;
    }

    @media (min-width: 400px) {
      width: 100px;
    }
  }
}

// 编译成

@media screen and (min-width: 900px) {
  .button {
    width: 200px;
  }
}

@media screen and (min-width: 400px) {
  .button {
    width: 100px;
  }
}

使用变量其实 node-sass 的特色,而@media使用这一特性能更好的复用代码

$media: screen;
$tablet: 768px;
$phone: 414px;

@media #{$media} {
  @media (min-width: $phone) {
    .button {
      width: 100px;
    }
  }
  @media (min-width: $tablet) {
    .button {
      width: 200px;
    }
  }
}

// 编译成

@media screen and (min-width: 414px) {
  .button {
    width: 100px;
  }
}

@media screen and (min-width: 768px) {
  .button {
    width: 200px;
  }
}

# @mixin

@mixin@extends有点相似,但@mixin会更灵活一些,@mixin需要配合@include使用。

@extends不同的是, @mixin只是定义,而不是真正的样式

  1. @extends会继承相同类名的样式,而@mixin只会复用指定的样式。
  2. @mixin还能通过参数功能来引入变量,类似于一个函数的方式来复用样式。
  3. @mixin会可以配合@supports, @media, @contents使用来增加灵活性

@mixin声明公共样式,后续的代码就能复用。 建议文件都使用下划线开头命名,例如_function.scss

// _function.scss

@mixin button {
  font-size: 14px;
  background-color: blue;
}

// button.scss
@import '_function' .submit-button {
  @include button;
  color: #07a123;
}

// 编译成
.submit-button {
  font-size: 14px;
  background-color: blue;
  color: #07a123;
}

通过参数功能来引入变量,第一个是字体颜色变量,第二个是宽度变量,默认值是 200px

// _function.scss

@mixin button($color, $width: 200px) {
  font-size: 14px;
  background-color: blue;
  color: $color;
  width: $width;
}

// button.scss
@import '_function' .submit-button {
  @include button($color: #07a123);
}

// 编译成
.submit-button {
  font-size: 14px;
  background-color: blue;
  color: #07a123;
  width: 200px;
}

配合@supports, @media, @content

@content的作用是自定义内容,就是@include后的花括号内容将替代@content

@mixin width-screen($width) {
  @media only screen and (min-width: $width) {
    @content;
  }
}

.button {
  @include width-screen(200px) {
    width: 100px;
  }
}

// 编译成
@media only screen and (min-width: 200px) {
  .button {
    width: 100px;
  }
}

@supports是原生 css 规则,用来判断当前环境是否支持某一个 css 特性。例如适配 iphoneX

@mixin iphoneX() {
  @supports (bottom: constant(safe-area-inset-bottom)) or
    (bottom: env(safe-area-inset-bottom)) {
    @content;
  }
}