FrankKai.github.io
FrankKai.github.io copied to clipboard
如何理解用于组件样式覆盖的:global?
:global
:global
是css-modules的一个概念,用于将当前选择器从局部作用域提升到全局作用域。
:global switches to global scope for the current selector respective identifier
应用场景
- UI库或者第三方组件样式覆盖(例如ant-design)
举个例子
覆盖ant-design Tab组件的.ant-tabs选择器。
这是antd的默认样式:
.ant-tabs {
height: 100%,
}
我的组件想要应用的样式(此时没有加:global)
.parent-container {
.ant-tabs {
height: 100%,
}
}
最终渲染结果:
.parent-container_2Uevo7d1cc .ant-tabs_1V-U-7d1cc {
height: 100%;
}
css modules默认使用的local作用域,因此如果直接添加.ant-tabs,那么css module的编译器会将.ant-tabs认为是组件自定义的class。
最关键的是:我们应用的ant-design的Tab组件,此时它的class名称还是叫.ant-tabs,而不是.ant-tabs_1V-U-7d1cc
。
所以Tab组件的样式仍然应用原生的.ant-tabs,.ant-tabs_1V-U-7d1cc这个样式规则生成了,但实际上页面上根本没用对应的DOM元素应用这个规则。
我的组件想要应用的样式(此时加了:global)
.parent-container {
:global {
.ant-tabs {
height: 100%,
}
}
}
最终渲染结果:
.parent-container_2Uevo7d1cc .ant-tabs {
height: 100%;
}
通过:global{ ...rules }选择器,可以将花括号中的规则提升为全局作用域(其实也就是不再为花括号中的class生成hash唯一标记)。
例如我们的例子中,ant-design的Tab组件应用的样式是.ant-tabs,而我们生成的规则也正好是.parent-container_2Uevo7d1cc .ant-tabs,并且因为css选择器的权重计算,后者权重更高,因此可以覆盖parent-container_2Uevo7d1cc下的Tab组件的样式规则。
:global
会影响到其他组件吗?
为什么要强调parent-container_2Uevo7d1cc呢?因为这个规则会精确作用于parent-container_2Uevo7d1cc下的Tab组件。不会影响其他组件中的Tab组件的样式规则,因为parent-container后面有一串hash。
对于其他组件来说,分两种情况:
- 没有自定义:global .ant-tabs规则
- 有自定义:global .ant-tabs规则
没有自定义:global .ant-tabs规则
如果没有自定义:global .ant-tabs规则,那么会默认使用原生的.ant-tabs。
因为如果没有自定义规则的话,在打包出的css文件中,不会生成指向子组件.ant-tabs的规则。
有自定义:global .ant-tabs规则
假设有2个组件,伪代码如下:
parent-containter组件自定义.ant-tabs规则。
<div class="parent-containter">
<Tabs />
</div>
.parent-container {
:global {
.ant-tabs {
height: 90%,
}
}
}
最终生成的规则为:
.parent-container_2Uevo7d1cc .ant-tabs {
height: 90%;
}
parent-containter-another组件自定义.ant-tabs规则。
<div class="parent-containter-another">
<Tabs />
</div>
.parent-container-another {
:global {
.ant-tabs {
height: 80%,
}
}
}
最终生成的规则为:
.parent-container-another_3fDso13adf .ant-tabs {
height: 80%;
}
通过最终生成的规则可以看出,2个组件可以生成各自的.ant-tabs规则,因此是互不影响的,不会互相影响。