css的规则是全局的,按理说是没有作用域这个概念的,任何一个样式的规则对全局都是有效的,而要想产生局部的作用域,唯一的方法就是使用一个独一无二的名字,不与其它的选择器重名,这个便是CSSModule的做法
局部作用域 :local
局部作用域语法:local(.className),等同于.className 也是CSS Module的默认行为,它会将 className 按照我们约定的格式进行转换
例如:
我定义一个className={style.demo} ,配置默认采用css module
.demo { margin: 50px; border: 1px solid red; width: 300px; height: 40px; height: 300px;}
然后再使用:local
:local(.demo) { margin: 50px; border: 1px solid red; width: 300px; height: 40px; height: 300px;}
两次代码转义之后就是如下图所示:可以看出是demo按我预定的格式转成了d_demo并且 :local(.demo)和.demo是等价的
全局作用域 :global
凡是使用global声明的class,都不会按照我们定义的格式进行转换,简单点说就是css module 不去处理
例如
使用gloabl 此时我们就不能再这样些了className={style.demo},二是写出这样 className='demo',代码如下:
:global(.demo) { margin: 50px; border: 1px solid red; width: 300px; height: 40px; height: 300px;}
同等与
:global { .demo { margin: 50px; border: 1px solid red; width: 300px; height: 40px; height: 300px; }}
展示效果:
![image.png]
CSS Module 优雅的覆盖样式
正常使用CSSModule可以防止样式被覆盖可以很好做样式隔离,但通常我们通用模块的组件的class或是第三方组件class不一定能满足我们的使用,需要进行样式覆盖,下面就介绍了利用CSSModule的作用域,那如何更优雅的覆盖样式,避免全局污染呢?
Html结构和css样式
<div className={[$style.demo, 'demo1']}> <div className='demo2'>2</div> <div className='demo3'>3</div> </div> <style>.demo1 { border: 1px solid red;}.demo2 { font-size: 24px;}.demo1 .demo3 { font-size: 24px; color: red;}</style>
覆盖某元素下的子元素样式
更改demo2的字体大小,如下代码适合修改demo下的多个子元素
.demo { margin: 50px; width: 300px; height: 300px; :global { .demo2 { font-size: 48px; } }}
或是下面的写法,这种写法适用于单个或比较少的情况
.demo { margin: 50px; width: 300px; height: 300px; :global(.demo2) { font-size: 48px; }}
上面情况适用于对某个组件子元素的样式进行覆盖,效果如下所示:
同级高权重的样式覆盖
这里关于css的权重,权重高的可以覆盖权重底的,不太了解的有兴趣可以了解一下,这不是重点就不说了
按上面示例,设置demo3的样式会有效吗?
.demo { :global(.demo3) { font-size: 18px; }}
可想而知肯定是覆盖不了demo3的样式的,如下图所示:
那该如何解决呢?在加一层,可以解决,那不加呢?
:global :local(.demo).demo1 .demo3 { font-size: 18px;}
或
:global { :local(.demo).demo1 { .demo3 { font-size: 18px; } }}//或者:global { :local(.demo) { &.demo1 .demo3 { font-size: 18px; } }}
都可以轻松的覆盖掉这些样式,也可以尽量避免使用important处理导致样式难以更改,效果如下:
可以在掘金查看