前段时间在 review 同事代码时,看到他使用了一个我很陌生的语法:global,第一眼看上去有点像是伪类,出于好奇就去了解了下这个语法,通过这篇文章也和大家分享下
关于 :global
大家都知道 css 的规则是全局生效的,即相同的类名都会命中相同的 css 样式规则。而为了解决类名易重复的问题,我们可以借助一些构建工具,将组件的类名转换成唯一的类名
以 webpack 提供的 css-loader 为例:
module.exports = {
module: {
rules: [
{
test: /.css$/,
use: ['css-loader'],
options: {
modules: true, // 启用 css 模块
},
},
]
}
}
通过 css-loader 可以将类名编译成一个哈希字符串,以达到类名不重复的目的;举例:
编译前:
// index.jsx
import React from 'react';
import style from './App.css';
export default () => {
return (
<h1 className={style.title}>
Hello World
</h1>
);
};
/* index.css */
.title {
color: red;
}
编译后:
// index.jsx
<h1 class="_3zyde4l1yATCOkgn-DBWEL">
Hello World
</h1>
/* index.css */
._3zyde4l1yATCOkgn-DBWEL {
color: red;
}
而 :global 语法就是 css 模块提供的一种特殊语法,通过这种方式声明的 class 不会被转换成哈希字符串;举例:
编译前:
.title {
color: red;
}
:global(.title) {
color: green;
}
编译后
._3zyde4l1yATCOkgn-DBWEL {
color: red;
}
.title {
color: green;
}
那么在什么场景下我们会希望一些类名不被转换呢?
适用场景
对组件样式进行复写
在一些业务场景中,有时我们需要对一些通用的公共组件进行业务的定制化,这种情况下我们一般都会匹配组件的类名并对样式进行改写;举例:
.title {
& > .antd__menu-title {
padding: 0;
}
}
但由于我们开启了 css modules,导致类名会被转换成哈希字符串,使得我们的改写不生效,这种情况下我们就可以通过 :global 语法将组件的类名进行声明,使得这类 class不会被转换,组件的样式就能成功被改写
.title {
&:global( > .antd__menu-title) {
padding: 0;
}
}
其他适用场景还有待补充