CSS Modules & Sass

CSS Modules

问题:
CSS 的规则都是全局的,任何一个组件的样式规则,都对整个页面有效。随着我们应用中组件的增多,很容易会出现类名冲突引发样式混乱。

解决方法:
产生局部作用域的唯一方法,就是使用一个独一无二的类名,不会与其他选择器重名。这就是 CSS Modules 的做法。它可以自动帮我们生成唯一的类名,这样就可以保证某个组件的样式,不会影响到其他组件。

基本使用

create-react-app 生成的项目会将 *.module.(scss|css) 文件使用 Css Module, 不需要做多余的配置。

import * as React from "react";
import style from "./style.module.scss";

export default class Main extends React.Component {
  render() {
    return (
      <div className={style.body}>
        <div className={style.btns}></div>
      </div>
    );
  }
}

全局作用域

使用 :global 的语法,就可以声明一个全局的规则

:global(.App-link) {
  color: #61dafb;
}

Class 组合

在 CSS Modules 中,一个选择器可以继承另一个选择器的规则,这称为 “组合”
通过 composes: 类名 的方法实现

.font {
  color: red;
}

.header {
  composes: font;
}

输入其他的模块

选择器也可以继承其他 CSS 文件里面的规则

定义一个 another.module.css

.font {
  color: blue;
}

在 App.module.css 中

.header {
  composes: font from "./another.module.css";
}

Sass

简介

Sass 是一个 CSS 预处理器,扩展了 CSS3,增加了规则、变量、混入、选择器、继承、内置函数等等特性,可以帮助我们减少 CSS 重复的代码,节省开发时间。Sass 的文件后缀名是.scss,意思是 sassy css。

使用

create-react-app 创建的 react 项目,默认就是支持 Sass 的,使用只需要安装一下 sass 这个包。

npm i sass -D

变量(Variables)

$width: 10px;
$height: $width + 10px;
$color: #f00;

.header {
  width: $width;
  height: $height;
  color: $color;
}

现在 CSS 支持原生变量了,而且是动态的,有些时候使用原生变量会是一种更好的选择,如果需要考虑兼容性,可以使用 Sass 的变量

混合(Mixins)

Mixin 是一种将一组属性从一个规则集混入到另一个规则集的方法。假设我们定义了一个类如下

@mixin bordered() {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

如果我们想要在其他类中混入这些属性,只需要像函数一样调用他们即可:

.menu a {
  color: #111;
  @include bordered();
}

.post a {
  color: red;
  @include bordered();
}

bordered 所包含的属性就同时出现在 .menu a 和 .post a 中了

嵌套(Nesting)

Sass 提供了嵌套代替层叠或者与层叠结合使用的能力,假如我们有下面的 CSS 代码

#header {
  color: black;
}
#header .navigation {
  font-size: 12px;
}
#header .logo {
  width: 300px;
}

如果使用 Sass

#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

还可以和伪类或者子元素选择器,如

#header {
  color: black;

  &:hover {
    color: red;
  }

  & > span {
    font-weight: bold;
  }
}

过深的嵌套只会让代码难以维护,建议嵌套不要超过三层,如果出现要嵌套超过三层的情况,应该考虑如何优化选择器的设计。

模块(Modules)

我们可以将 Scss 文件拆分成模块单一的文件,需要用到某个模块时,可以从那个 Scss 文件导入进来,例如我们可以把变量样式都定义在一个单独的 Scss 模块中,其他文件都来引用它,通常我们用这种方式来控制主题样式,当我们需要修改主题的时候,只需要修改变量文件中的值,然后重新编译即可。

vars.scss

$primaryColor: #f00;
$textColor: #666;

theme.scss

@use "vars";

#header {
  background-color: vars.$primaryColor;
  color: vars.$textColor;
}

Q.E.D.


永远自由,永远热爱