Skip to content

⚠️ Important Notice

This post was last updated on: which was . Please pay attention to its timelines.

背景

在原生的CSS中,存在很多痛点需要优化:

  • 语法简陋:没有变量、函数等高级特性
  • 全局作用域污染:类名是全局通用的,很容易冲突
  • 选择器规则复杂,难以维护,过长还可能导致CSS性能问题
  • 样式的复用性差
  • 样式生效有一些隐式规则:比如样式的继承规则、类名声明的先后顺序等都会影响最终的样式

优化方案

由于这些痛点的存在,导致CSS的开发效率低下,维护成本也比较高。

统一类名的命名规则

BEM(Block Element Modifier)命名规则 根据该命名规则,样式类名的命名方式是:block__element--modifier.

  • block:块 功能模块的名称,比如一个按钮.btn
  • element:元素 块的组合部分,一般是元素的功能,比如下拉元素.block__dropdown
  • modifier:修饰符,一般是元素的状态,比如禁用状态.block__dropdown--disabled

通过该命名规则,可以为不同功能的元素和状态定义不同的样式类名,从而提高代码的可维护性。

缺点

  • 类名的命名规则比较复杂,需要记忆
  • 依靠开发者来维护, 需要成本并且容易出错

CSS预处理器

Scss以及Less等CSS预处理器可以提供一些高级特性,比如变量、函数、嵌套等,可以提高代码的可维护性。

缺点

  • 并不是原生的,需要经过处理编译之后才能在浏览器中生效,增加了成本
  • 需要学习新的语法

CSS后处理器

PostCSS是典型的CSS后处理器,对已有的CSS进行处理。可以提供一些高级特性,比如自动添加浏览器兼容前缀、自动添加单位、CSS代码压缩等。

缺点

  • 也需要额外的学习成本,并且需要配置才能生效
  • 外搭的,也会增加构建成本

原子化CSS

代表工具就是TailwindCSS,通过预定义的类名来细粒度的控制CSS样式,进而提高CSS开发效率,从根本上避免了样式冲突。

缺点

  • 预定义的类名比较多,需要记忆,增加了学习成本
  • 类名可能过长,对代码的可读性有一定影响
  • 复杂的动画等是不能满足的

CSS in JS

CSS in JS是通过JS来编写CSS样式,然后将动态生成的CSS样式注入到HTML的style标签中。并且通过复用JS的作用域,增强了CSS的能力。

代表工具是styled-components以及emotion.js

styled-components为例,动态生成的CSS样式是不固定的,通过hash来生成唯一的类名,从而避免了样式冲突。

缺点

  • 动态生成的CSS,所以会有一些性能开销
  • 组件内使用的话,生成的类名不固定,复用时难以控制内部样式

CSS in JS Props方案

借助Babel等编译工具,直接在JSX的css属性上添加样式,然后再编译成CSS。

但是这种方式本质还是CSS in JS,所以缺点还是一样的。

CSS Module

CSS Module是通过CSS预处理器来实现的,通过CSS Module可以将CSS样式封装到一个模块文件(通常是xxx.module.less)中,从而避免了样式冲突。

缺点

  • 需要添加额外的配置来控制生成的类名。
  • 对于组件来说,内部的类名也是难以复用的,因为类名一般都是根据路径来动态生成的。

上一次更新: