Unknown Me

一些 CSS 管理方案的优缺点

Update: 2021.12.13

一年过去,更新了一些自己的想法

  • 对 Tailwind CSS 等方案更加开放
  • 搭配方案区分开组件和应用

从自己的角度看,结合 React 使用,梳理下几种 CSS 管理方案的优缺点。

# 方案

Vanilla CSS、Less/Sass/Stylus

  • 要想类名,很累
  • 类名容易冲突。为了解决冲突需要自己写嵌套,但是结构容易越写越深
  • 从 CSS 找组件困难,删完一处组件之后,不太敢删对应样式,怕别处也用到,没有安全感
  • 组件找 CSS 也困难,有时会不知道对应样式写在哪

BEM

  • 通过规范来规避类名冲突
  • 样式都在一个层级,不用担心优先级的问题了,可以简化层叠规则
  • 但是不是强约束,还是要想名字,更累了

Inline styles

  • 可以直接从 JS 传值到 style,有编程能力
  • 但是全都这样写就太累了,一般作为补充手段
  • 驼峰属性毕竟不是正路 CSS 写法
  • 无法解决部分问题,如覆盖已有样式、伪类、动画等

CSS Modules

  • 通过编译生成全局唯一类名,完全不用担心冲突
  • 写样式就可以全部扁平,不再需要嵌套
  • 从组件找 CSS 容易,沿着 import 去找就行
  • 语法比较定制,有点怪

Styled Components / Emotion / JSS 等 CSS-in-JS 方案

  • 不用再想样式类名了,有 JSX 组件名就行
  • 同样是会生成全局唯一类名,不用担心冲突
  • 不用 CSS, JSX 之间跳来跳去,一个文件搞定
  • 市面上方案太多了,万一选择的方案被淘汰,就会带来维护风险
  • 原本一句简单 HTML 的事情,为了样式非要变成组件,感觉是过度抽象
  • 适合做组件库时使用,直接交付一个 JS 就完事了,样式都是从 JS 释放出来的
  • 不太适合做普通应用,样式都由 JS 动态释放,CSS 没法抽出来就没法利用浏览器缓存

Tailwind CSS / Windi CSS

  • 相当于写原子类,但是可以按需生成 CSS,非常节省代码体积
  • 不用再想样式类名了,可是要想
  • 有很高的记忆成本,初期需要一直查字典
  • 复杂的样式会在 HTML 上留下一长串的 className,略丑

# 个人选择

认真梳理了下个人习惯和业务场景,目前主要写的样式可以分成这几种

  • 模块的定制样式,只适用在这个模块内,占比大约 80%
  • 公用样式,可以多处复用的,占比大约 10%
  • 全局样式,指的是 html,body 这种,一般整个页面里就写一次,占比不足 1%
  • 动态样式,依赖 JS 计算的,也占比不足 1%
  • 覆写第三方库样式,占比大约 10%

特殊的是,设计师会给我们提供色表、字表,我会先将这些抽成变量,所以一定会引入 CSS 预处理器,或者是 CSS Variables

基于以上,我会考虑这样的搭配方案

新的大型项目:

  • 局部样式使用 CSS Modules 来避免类名冲突,在页面/组件里使用
  • 公用样式和全局样式,继续写 Vanilla CSS 就好
  • 动态的部分,用 Inline style 完成
  • 覆写第三方库样式/为第三方库的类写样式,使用 CSS Modules 的 :global 解决

新的小型项目、个人项目:

  • 考虑使用 Windi CSS

组件库:

  • 我会选择 Styled Components 或类似的方案,因为一个文件能装完,类似 Vue 的单文件组件体验

# 参考文章