CSS Modules 方案

1,770 阅读2分钟

在讲CSS Modules之前,先想想什么是CSS Module?

在我眼中CSS Module是对css进行模块化的管理,更加深入的解释就是用来管理css样式的导入与导出。灵活按需导入以便复用代码,导出的时候要合理的分割域的界限。

CSS Module面对的问题

模块化实际过程中遇到的问题有如下几点:

  1. 样式污染
  2. 命名混乱
  3. 无法共享变量,具体来说,在主题样式文件库中设置了默认样式,然后想要在js中去获取,在原先的css体系中很难做到,你要通过dom查询去获取对应的样式。
  4. 代码压缩不彻底,比如说,你用了sass、less之类的内容,他们会在被包裹的类名上再加上包裹他的类名,无法做到很好地压缩

进程后移,CSS Module的发展中,出现了sass、less等一系列解决css编程能力弱的问题和样式污染的问题,但是他们并没有很好地解决模块化其他的问题

在之前,还出现过一种方案叫 css in js,这种写法相当于完全抛弃了css,在js中通过hash映射来写css,这个写法的好处和坏处都很明显。

然后就是我们的CSS Modules, CSS Module的问题他都能解决的比较好

CSS Modules

CSS Modules的官方文档如下:github.com/css-modules…

简单的例子来描述写它的使用方式,

首先在webpack中进行对应的设置,之后进行对应的引用

 /*webpack.js*/
css?modules&localIdentName=[name]__[local]-[hash:base64:5]
/*Button.css*/
.normal{}
.disabled{}
/*Button.js*/
import styles from './Button.css'
render(){
    reutrn(
        <button class=${styles.normal}></button>
    )
}
最终生成的html如下
<button class="button-normal-abc5436"></button>

后面的abc3546是按照localIdentName自动生成的class名称,按照给定算法生成的序列码,这样处理之后,大大降低了项目中样式覆盖的几率 。同时生成更短的class名可以提高css的压缩效率

默认情况下,样式是局部内容,如果要切换成全局的样式可以用:global进行包裹

样式复用在CSS Modules中也是可以做到的,相对于less sass来说麻烦一点,需要用composes来组合样式,当然现在CSS Modules也是可以结合less的

.base{}
.normal{
    composes:base
}

以上CSS Modules的命名规则是源于BEM的。BEM是一种css命名模板,具体内容如下:

B:block,对应模块名,如dialog

E:element 对应模块中的节点,如button

M:modifier 对应节点的状态,disabled

最终class名 dialog__button--disabled 在很多大型项目中都可以看到这样的命名写法

CSS Modules实现变量共享

config.css
css{
    $primary-color:#ffffff;
}
app.js
import style from 'config.css'

console.log(style.primaryColor)

解决频繁书写styles的副作用

不过CSS Modules在实际开发中会带来书写的副作用,每一个class前面都需要加一个styles,这样增加了书写的负担,如果不想频繁的书写,可以使用react-css-modules库,通过高阶组件的形式避免重复输入css 核心代码如下:

import React,{Component} from 'react'
import styles from './config.css'
import CSSModules from 'react-css-modules'

class Dialog extends Component{
    render(){
        return(
            <div styleName={root}></div>
        )
    }
}

export default CSSModules(Dialog,styles)

这样书写之后的好处有如下几个:

  1. 省去了styles的重复书写
  2. 如果想要写全局样式,直接用className书写就可以
  3. styleName关联一个undefined的CSS Modules时,我们可以得到一个警告
  4. 保证css的样式来源的单一明了