CSS Modules 通过以模块化的方式编写 CSS 代码,在 JavaScript 文件中导入和使用,自动生成唯一的类名,隔离样式,避免类名冲突。
style.module.scss
.more {
&List {
&Btn {
&:hover {
background: #fff;
}
}
}
}
index.tsx
import styles from './style.module.scss'
<Button className={styles.moreListBtn}></Button>
开发时生成的类名就长这样:
.__src_views_xxx_module__moreListBtn-a7f49f:hover {
background: #fff;
}
一般都是生成一个类名。
一个类名可能就会遇到优先级低无法覆盖样式的问题,比如Button就有这样一个外部样式:
@media (hover: hover) {
button.Btn:hover:not(.Btn--primary):not(.Btn--outline):not(:disabled) {
background: rgba(0, 0, 0, .04);
}
}
显然上面 CSS Modules 生成的样式优先级低于外部样式,自定义样式就不会生效。
!important
是不推荐的,MDN 也说了:使用 !important
是一个坏习惯,应该尽量避免,因为这破坏了样式表中的固有的级联规则 使得调试找 bug 变得更加困难了。
先复习下 CSS 优先级:
下面列表中,选择器类型的优先级是递增的:
类型选择器
:(例如,h1
)和伪元素(例如,::before
)类选择器
:(例如,.example
),属性选择器(例如,[type="radio"]
)和伪类(例如,:hover
)ID 选择器
:(例如,#example
)。
通配选择器(*
)、关系选择器(+、>、~、" "、||
)和 否定伪类(:not()
)对优先级没有影响。(但是,在 :not()
内部声明的选择器会影响优先级)。
ID 选择器
在 CSS Modules 中通常不建议使用。那么可以通过添加类选择器
提升优先级。
@media (hover: hover) {
button.Btn:hover:not(.Btn--primary):not(.Btn--outline):not(:disabled) {
background: rgba(0, 0, 0, .04);
}
}
上面这段 CSS 的优先级是 051
,即 0
个ID 选择器
、5
个类选择器
、1
个类型选择器
。
.__src_views_xxx_module__moreListBtn-a7f49f:hover {
background: #fff;
}
对于 <Button className={styles.moreListBtn}></Button>
,生成的类名只有2个类选择器
,需要添加4个类选择器
使优先级达到 061
就可以覆盖外部样式。
那么如何添加类选择器
又不会影响 CSS Modules 的使用呢,这时就可以通过否定伪类(:not()
)添加凑数类名,既可以增加类选择器
提升优先级,又不会影响 CSS Modules 的使用。
.more {
&List {
&Btn:not(.priority1):not(.priority2):not(.priority3):not(.priority4) {
&:hover {
background: #fff;
}
}
}
}
生成的类名如下:
.__src_views_xxx_module__moreListBtn-a7f49f:not(
.__src_views_xxx_module__priority1-a7f49f
):not(
.__src_views_xxx_module__priority2-a7f49f
):not(
.__src_views_xxx_module__priority3-a7f49f
):not(
.__src_views_xxx_module__priority4-a7f49f
):hover {
background: #fff;
}
这样就有6个类选择器
了。