Skip to content

常见方案

CSSCSS-in-JSTailwindCSS
学习曲线
动态样式支持
可维护性(配合BEM等)(模块化、隔离)(HTML中类名较多)
性能
适合场景静态页面、小型项目React等现代框架快速开发、设计系统

全面对比

解决方案代表/示例核心概念/描述优点缺点示例/实践
CSS 预处理器Sass、Less、Stylus• 变量、嵌套规则、混合器(Mixin)、继承(Extend)、运算 • 提供变量、嵌套、循环等高级功能 • 提供强大工具和逻辑控制(条件、循环)• 提升CSS开发效率,代码模块化,易维护 • 提供逻辑控制功能 • 提升可读性与复用性• 需要编译,增加开发流程复杂性 • 生成CSS可能冗余,性能优势较低使用Sass编写变量和嵌套规则
CSS in JSStyled-components、Emotion、JSS• 样式与组件绑定,动态生成CSS • 支持模块化与作用域隔离 • 在JS中编写CSS,常用于React等框架• 与React等框架无缝集成,动态样式管理简单 • 避免全局样式污染 • 动态能力强,与框架集成度高• 运行时性能开销大 • 学习曲线较陡峭 • 依赖构建工具使用Styled-Components或Emotion编写样式
CSS模块化Webpack支持• 将CSS分隔为独立模块,通过工具生成独特类名 • 自动生成唯一类名避免冲突,样式按需加载 • 确保样式隔离• 避免命名冲突,性能优于CSS in JS • 适合模块化项目,维护性强 • 作用域隔离• 需要构建工具支持 • 动态样式支持不够灵活 • 上手复杂使用CSS Modules引入局部样式
原子化CSS / Utility-First CSSTailwind CSS、Bootstrap Utilities• 提供大量小型功能类名,通过组合构建页面 • 每个类名对应一个样式属性,样式通过类名组合实现• 快速开发,无需自定义CSS规则 • 样式统一,社区生态强大 • 减少样式冲突• 学习成本高(大量类名) • HTML文件样式类名多,可读性较差 • 类名杂乱使用TailwindCSS的类名组合
Scoped CSSVue scoped样式、Shadow DOM• 样式作用域限制在组件内 • 通过Vue的scoped或Web Components的Shadow DOM实现• 样式隔离强,代码结构清晰 • 不受外部影响 • 与组件绑定• 需要工具链支持 • 增加复杂性,全局样式覆盖困难 • 复杂项目中可能有性能问题Vue中通过<style scoped>实现样式隔离
Functional CSSTachyons• 样式为功能块,极简类名代表单一功能 • 类似原子化CSS,但更注重功能抽象化 • 通过工具函数生成,强调复用性• 功能清晰,简化CSS开发 • 易于理解和维护 • 减少重复代码,提高样式复用率• 可读性差,依赖文档记忆 • 学习成本较高使用Sass函数生成间距:@function spacing($value)
BEM命名规范-• 基于类名的命名约定:Block(模块)、Element(元素)、Modifier(修饰符)• 命名清晰,团队协作友好 • 无工具依赖,简单直接 • 清晰的语义和结构,高可维护性• 类名较长,增加代码冗长感 • 无法动态生成样式,灵活性低于CSS in JS • 手动管理易出错class="button__icon--large"
PostCSS-• CSS工具平台,通过插件提供功能扩展(如自动前缀、变量) • 支持工具链的灵活配置• 灵活性强,插件链可定制 • 与现代构建工具无缝集成 • 插件灵活,结合现代CSS标准• 学习插件配置复杂,增加开发成本 • 需要熟悉插件生态配置Autoprefixer和cssnano优化样式

如何对样式体系进行选型

  • 项目特点
    • 交付周期
    • 性能需求
    • 团队规模
    • 未来扩展需求
      • 模块化
      • 响应式
      • 动态样式
  • 团队能力
    • 技术栈工具链是否适配
    • 熟练度

CSS方案技术评审

  • 布局方案
    • Flexbox 一维布局,弹性盒模型
    • Grid 二维布局,复杂页面设计
  • 动画过渡
    • transition
    • @keyframes
  • CSS变量、计算属性
  • 媒体查询
    • @media
  • 命名规范
    • BEM 团队协作
    • 工具化/语义话/原子类
  • 性能
    • 避免重排,重绘
      • 避免position:absolute,float的复杂计算
      • transform实现动画和过渡
    • 优化
      • contain
        • 显式声明某个具有明确宽高的元素的渲染范围限制,(主要是跟子元素变动有关),以减少浏览器的重排和重绘工作。
      • will-change
        • 对会频繁样式变动的元素提前GPU加速优化
        • 常见于 CSS 动画、滚动视差效果等场景
        • will-change 会增加内存占用,过度使用可能降低性能。
        • 尽量仅在需要时使用,效果完成后移除 will-change。

CSS-in-Js方案

  • 背景
    • 由于组件化得到普及,这种方案能提供更好的动态样式和模块化
  • 主流
    • styled-components:易用,性能好
    • Emotion:可ts,灵活性
    • JSS:可复杂定制
  • 特性
    • 动态样式
    • Scoped
    • 嵌套、继承
  • 最佳实践
    • 性能:避免频繁修改
    • 安全:ts辅助书写样式属性
    • 主题系统切换
  • 限制
    • 大规模项目中的开销
    • 兼容性

原子化(以Tailwind为例)方案

  • 预定义类名,减少自定义样式从而提升生产效率
  • 配置文件定义主题色,断点
  • 高级用法
    • @apply提取复用样式逻辑
    • 动态值、状态修饰符
    • JIT优化(v3.0+后默认启用了)
      • 减少样式体积,提升构建速度,编译只生成最小需要的类
  • 实践
    • 类名排序、工具链规范以提升可读性

最佳实践

样式体系

  • 分层架构
    • Base Style全局样式基础
    • Components组件样式
    • Utilities工具类样式
  • 原子化样式结合组件化
    • 在小工具类 和 复用组件取得平衡
      • 例如daisyui,先使用复用组件类,然后使用小工具类微调
  • 工具链
    • Linter进行样式检查
      • stylelint,Prettier
      • 比如缩进,引号,命名规范(正则检查),空块的约束
    • CSS代码压缩,Tree Shaking
    • 或者将以上放在CI/CD中自动化进行

方案设计

  • SSR项目: CSS/Moduler 定义全局规则
  • ReactSPA:Css-in-Js 管理复杂交互
  • 小项目,POC(Proof of Concept)快速:Tailwindcss
  • 工具链
    • Postcss处理自动前缀,变量
    • Stylelint 保证代码规范

说实话Tailwind我觉得像daisyui那样去处理旧能很大程度避免HTML可读性极差的问题,虽然还是不如其他方案的HTML可读性,我觉得在团队规范合适的情况下,也适合大项目。