在写react项目使用antd-pro框架的时候,我们时常遇到需要覆盖antd样式的需求,可能会写出来这样的代码:
.export {
margin-top: 24px;
.ant-btn {
&:first-child {
margin-right: 16px;
}
}
}
}
引用样式的时候:import styles from ‘index.less’
然后发现完全不管啊!!!!怎么回事??
其实这里涉及到CSS Modules(加入了局部作用域和模块依赖)
为什么需要CSS Modules呢?
因为我们再开发项目的时候时常会遇到样式被覆盖的问题,在CSS Modules出来之前,一般都需要在自己的文件里面定义一个不会全局重复的样式名(比如按模块名命名等),然后在这个最外层样式里面继续使用less或者scss写样式,可是随着项目越来越大,参与的开发人员越来越多,命名越来越困难。所以就出现了CSS Modules。
为什么CSS Modules可以解决全局样式覆盖的问题?
CSS Modules,一般都会把样式文件进行模块化,即打包后每个样式文件类命名的class名都会被自动加上一串唯一的序列号。就像下图一样:
那我不想让他加序列号,就是想让这个样式作用到全局上,应该怎么办呢?
两种办法:
- 在全局的global.less里面写样式,他会作用到全局,不会加上序列表
2. 在自己的样式文件里面写,但是需要外层添加一层:global
.export {
margin-top: 24px;
:global {
.ant-btn {
&:first-child {
margin-right: 16px;
}
}
}
}
讲到这里我们可以就可以明白less里面antd覆盖样式不生效的问题了。
因为在你不加:global的时候,会在你写的antd的样式名后面自动加上了一串序列号。但是实际页面渲染出来的antd的组件是不带序列的,样式名匹配不上,自然不会生效了。
在外层加上:global,不会自动添加序列号,匹配得上,就会生效。
但是有几个在开发过程中需要注意的问题:
- 全局的样式按要求写到全局样式文件global.less里面
- 在各模块的样式文件里面也可以定义全局样式,加到:global里面即可。但是有风险,风险在于他会影响全局。如果本身就是想定义全局样式,请参考第一条的操作。
- 既然写到了自己的样式文件里面,我认为初心应该是只想改变当前页面的样式,那建议大家在最外层的标签加一个一级的样式名,避免泄露成全局样式
- 最外层的样式名不需要全局唯一,可以都使用同一个样式名,比如container等等。因为css Modules会自动生成一个唯一的序列号,不需要我们代码层面去保证。