CSS Modules 初探

787 阅读2分钟

局部作用域

CSS Modules采用使class类名变得独一无二,不与其他选择器重名,从而产生了局部作用域。

一个如下的React组件:

import React from 'react';
import style from './App.css';

export default () => {
  return (
    <h1 className={style.title}>
      Hello World
    </h1>
  );
};

App.css:

.title {
  color: red;
}

styles是App.css的引入,在jsx中就可以通过style.title匹配对应的class。

构建工具会将该类名style.title转化为一个哈希字符串,确保了其唯一性。

HTML:

<h1 class="_3zyde4l1yATCOkgn-DBWEL">
  Hello World
</h1>

CSS:

._3zyde4l1yATCOkgn-DBWEL {
  color: red;
}

全局作用域

CSS Modules允许使用 :global(:className) 的语法,声明一个全局规则,但是在组件内使用时如要使用该类名的样式,不能再以 {style.className} 的方式,而是直接采取 "className" 的形式。

修改上面的App.css:

.title {
  color: red;
}

:global(.title) {
  color: green;
}

修改React组件:

import React from 'react';
import styles from './App.css';

export default () => {
  return (
    <h1 className="title">
      Hello World
    </h1>
  );
};

如上修改,h1的内容将被渲染成green。

如果此时我的

<h1 className="title">
      Hello World
    </h1>

改为:

<h1 className={styles.title}>
      Hello World
    </h1>

则h1的内容将被渲染成red。

CSS Modules还支持显示的声明局部作用域, :local(:className) ,所以上面的App.css还可以写成下面这样:

:local(.title) {
  color: red;
}

:global(.title) {
  color: green;
}

个性化定制哈希类名

通过webpack.config.js去进行配置。

className的组合(继承)

修改App.css:

.className {
  background-color: blue;
}

.title {
  composes: className;
  color: red;
}

修改React组件:

import React from 'react';
import style from './App.css';

export default () => {
  return (
    <h1 className={style.title}>
      Hello World
    </h1>
  );
};

title继承了className的属性,渲染出来的h1是蓝色背景红色字体样式的。

composes只能是composes

编译以后的HTML:

image

编译以后的CSS:

image

className组合(继承)其他模块

新建一个another.css:

.className {
  background-color: blue;
}

修改App.css:

.title {
  composes: className from './another.css';
  color: red;
}

React组件不变,运行实例可以看到页面依然渲染出来的h1是蓝色背景红色字体样式的。

输入变量

CSS Modules 支持使用变量,不过需要安装 PostCSS 和 postcss-modules-values。

在一个公共文件里去定义一个colors.css,在里面定义变量:

@value blue: #0c77f8;
@value red: #ff0000;
@value green: #aaf200;

App.css引入这些:

@value colors: "./colors.css";
@value blue, red, green from colors;

.title {
  color: red;
  background-color: blue;
}

React组件不变,运行实例可以看到页面依然渲染出来的h1是蓝色背景红色字体样式的。

文章参考自阮一峰老师的文章,我是为了自己学习和记录。