CSS Module / global / local

1,585 阅读1分钟

CSS Module是常见的样式隔离方案,它的基本原理是打包时转换className,根据某种规则生成唯一字符串应用到dom节点中去。

以一个React项目为例:

import styles from './App.module.scss'

function App() {
  return <div className={styles['wrapper']}></div>
}

export default App
// App.module.scss
.wrapper {
  height: 100%;
}

微信截图_20220811180945.png

如上所示,CSS Module会将xxx.module.scss内的所有class转换成唯一字符串

我们也可以打印出来观察:

import styles from './App.module.scss'

console.log(styles)

function App() {
  return <div className={styles['wrapper']}></div>
}

export default App

微信截图_20220811181243.png

可以看到其实就是一个简单对象,以原class作为key,处理后的唯一字符串作为value

另外,在scss嵌套结构下,CSS Module依旧会对所有class进行处理

.wrapper {
  height: 100%;
  > .top {
    height: 30px;
    > .left {
      width: 50px;
    }
  }
  > .bottom {
    height: 20px;
  }
}

微信截图_20220811181610.png

那么我们发现,在这种情况下,想要正常使用的话,jsx代码会如下:

import styles from './App.module.scss'

console.log(styles)

function App() {
  return (
    <div className={styles['wrapper']}>
      <div className={styles['top']}>
        <div className={styles['left']}></div>
        <div className={styles['right']}></div>
      </div>
      <div className={styles['bottom']}></div>
    </div>
  )
}

export default App

微信截图_20220811182002.png

在一段代码中使用多个styles.感觉比较麻烦,怎么可以减少使用的频率呢?这时候可以用到CSS Module的关键字global

import styles from './App.module.scss'

console.log(styles)

function App() {
  return (
    <div className={styles['wrapper']}>
      <div className="top">
        <div className="left"></div>
      </div>
      <div className="bottom"></div>
    </div>
  )
}

export default App
.wrapper {
  height: 100%;
  > :global(.top) {
    height: 30px;
    > :global(.left) {
      width: 50px;
    }
  }
  > :global(.bottom) {
    height: 20px;
  }
}

微信截图_20220811182448.png

但是这样的话global又要多次使用,还有没有更加简洁的写法呢?有,使用CSS Module的另一个关键字local

:global {
  :local(.wrapper) {
    height: 100%;
    > .top {
      height: 30px;
      > .left {
        width: 50px;
      }
    }
    > .bottom {
      height: 20px;
    }
  }
}

jsx代码部分不变

相当于,使用:global开启白名单模式,在global下,需要显式使用local开启classname处理