学习一下CSSModule

什么是cssModule

在js中,我们有大量模块化解决方案,比如es6中的export和import导入导出以及commonJS中的require以及module.export都可以实现私有变量以及全局变量。而在css中,为了实现这css的模块化,主要有下面两种方法:

  • css in js。使用js或者json格式来书写样式,并将样式生成inline-style的形式,这种方式无疑可以让css拥有js的模块化功能。但是,同样缺点也十分明显,几乎无法利用css中特性,比如媒体查询,以及面对hover,active等伪类的处理比较麻烦。
  • cssModule。这个方法依然使用css,但是使用js来进行状态管理,能最大化地结合现有 CSS 生态和 JavaScript 模块化能力。不过可能刚上手写起来可能有点不太习惯

传统css开发中面临的问题

  • 全局污染 css中采用全局选择器的机制来设置样式,这种方式的优点是方便复用样式,缺点是可能导致需要对某些样式进行重写,必要甚至需要加上!important;
  • 命名混乱 多人协作开发时,无法不导致样式冲突,选择器的写法会越来越复杂,容易形成不同的命名风格,造成混乱;
  • 无法确定依赖关系 有时候我们可能只需要css文件中的一部分样式,但是一旦link一个css文件,文件会被全部加载;
  • 无法共享变量 有时候可能需要js和css共享一个变量,但是显然在传统的css中无法实现;
  • 压缩不够彻底 压缩工具无法对选择器进行压缩,而一般为了方式样式冲突,选择器的长度都不会太短。

使用方法

参考了阮一峰大神的《CSS Modules 用法教程》

1、局部变量

css文件的内容

.title {
  color: red;
}
.test-css{
  font-size:40px
}

然后在需要使用的js文件中引入css文件
在这里插入图片描述
在这里会输出
在这里插入图片描述
同时,html结构中会插入相应的内联样式
在这里插入图片描述
然后这样直接使用
在这里插入图片描述
在这里使用了一个classnames的插件,可以很方便对类名根据条件进行拼接处理。

注意 :css中test-css类名转成js之后,还是以test-css这样的名称存在

2、全局变量

如果我们想直接使用title而不是用styles.title,可以设置一个全局变量
在这里插入图片描述
在类名的前面加上一个:global标识就表明是一个全局变量,顺便一提,普通的默认是带上了
:local标识(可以不用写),表明局部变量。

使用时可以直接进行使用了,而不需要用styles.title
在这里插入图片描述
相同的样式属性,优先级高优先,优先级相同,后面的优先(无论是全局还是局部)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、定制hash类名

css-loader中默认的类名生成规则是 [hash:base64],我们可以通过在webpack中进行配置
比如:

{
  test: /\.css$/,
  loader: "style-loader!css-loader?modules&localIdentName=[path][name]---[local]---[hash:base64:5]"
},

会生成
在这里插入图片描述
其中各个部分对应为:

  • demo03-components-app对应path;
  • App对应name(文件名)不包含后缀;
  • local对应类名,如title;
  • hash:base64:5生成5位base64码

4、组合composes

cssModule中建议使用组合的方式来书写复杂样式,比如

.className {
  background-color: blue;
}

.m20{
  margin:20px;
  padding:20px;
}

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

其中title类名样式中包含了className和m20类名的样式,可以在title中使用composes方式进行组合,最终的编译结果为
在这里插入图片描述
在这里插入图片描述
包含三个值,分别为classNamem20以及title剩余内容生成的base64。

全局变量不能使用组合

.className {
  background-color: blue;
}

.m20{
  margin:20px;
  padding:20px;
}

.title {
  composes: className m20;
  color: red;
}
:global(.all){
  composes: title;
}

在这里插入图片描述
表示组合只允许在 单个的局部选择器 上。

5、引入其它模块

可以在compose中引入其它css中的变量


//app.css

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

//another.css

.className {
  background-color: blue;
}
.another{
  font-size:30px;
}

引入文件之后,会将外部文件中的内容全部引入
在这里插入图片描述
可以看见,我们只使用了className,但是将another也一起进行了编译

总结

总结一下,使用cssModule尽量遵循以下原则

  • 不使用选择器,只使用class名来定义样式;
  • 不层叠样式,只使用一个类名把样式定义好;
  • 不嵌套,尽量使用组合的方式定义样式

猜你喜欢

转载自blog.csdn.net/weixin_43801564/article/details/86089401
今日推荐