Css Module global和local巧妙的覆盖样式

7,772 阅读3分钟

CSS Module 作用域

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;
  }
}

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处理导致样式难以更改问题,也可以避免直接使用global导致的全局样式污染问题