Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何理解用于组件样式覆盖的:global? #253

Open
FrankKai opened this issue Jun 15, 2021 · 0 comments
Open

如何理解用于组件样式覆盖的:global? #253

FrankKai opened this issue Jun 15, 2021 · 0 comments
Labels

Comments

@FrankKai
Copy link
Owner

FrankKai commented Jun 15, 2021

: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规则,因此是互不影响的,不会互相影响。

@FrankKai FrankKai added the CSS label Jun 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant