传统开发模式
一般而言,在 Web 开发中,我们都会将 CSS、HTML、JavaScript 三者分离。
HTML 负责网页的结构。
CSS 负责网页上各个元素的展示样式(效果)。
JavaScript 负责网页与用户的交互(逻辑)。
将计算机程序划分为不同部分的设计原则,就是关注点分离原则(Separation of Concerns,简称 SoC)。因此,HTML、CSS、JavaScript 三者分离正是关注点分离原则的典型应用。
flowchart LR
HTML(HTML 结构) <---> CSS(CSS 效果)
HTML <--> JavaScript(JavaScript 行为)
style HTML fill:#52c41a,color:white,stroke:#52c41a
style CSS fill:#1890ff,color:white,stroke:#1890ff
style JavaScript fill:#fa8c16,color:white,stroke:#fa8c16
什么是 CSS-in-JS
CSS-in-JS是一种样式技术,使用 JavaScript 编写 CSS,也就是把 CSS 集成到 JavaScript 中。这看起来有点反直觉。
解析这段 JavaScript 时,会生成 CSS(通常作为<style>元素)并附加到 DOM 中。
为什么会有 CSS-in-JS?
传统开发中,我们通常直接在 HTML 中引入 CSS 文件,样式缺少作用域隔离,很容易发生样式互相覆盖。
现代开发逐步走向组件化,也希望能让样式围绕组件边界生效。CSS-in-JS恰好可以做到“就近管理样式、减少污染”。
解决作用域问题
使用CSS-in-JS,就可以借助 JavaScript 作用域模拟 CSS 作用域,让 CSS 拥有独立的作用域,阻止 CSS 代码泄露到组件外部,防止样式冲突,使样式只在组件内部生效,从而解决 CSS 无作用域的问题。
增加组件的独立性、可移植性
移动组件时,我们可能会忘记样式文件,甚至不知道样式文件在哪里。使用CSS-in-JS,组件就是一个独立文件,只需移动组件本身即可,开箱即用,从而轻松创建松耦合的应用。
可重用性
只需编写一次,即可在任何地方运行,不仅可以在同一个应用程序中重用组件,还可以在使用相同框架构建的其他应用程序中重用组件。
动态性
CSS 缺乏动态性,不能根据条件给某个元素添加样式。使用CSS-in-JS,可以借助 JavaScript 的动态能力为元素动态添加样式,让复杂的逻辑也能应用于样式规则。特别是对于需要创建复杂动态 UI 的场景,它是理想的解决方案。
按需引入
随着业务量的增加,组件越来越庞大,因此需要按需引入。采用tree-shaking方式,使用CSS-in-JS更容易做到按需引入。
因此,CSS-in-JS方案就是为了解决 CSS 的局限性,例如缺乏动态功能、作用域和可移植性等问题。
优缺点
flowchart LR
CSS-in-JS(CSS-in-JS) --> 优点(优点)
CSS-in-JS(CSS-in-JS) ---> 缺点(缺点)
优点 --> 作用域(作用域):::otherNode
优点 --> 可移植性(可移植性):::otherNode
优点 --> 可重用性(可重用性):::otherNode
优点 --> 动态性(动态性):::otherNode
优点 --> 按需引入(按需引入):::otherNode
缺点 --> 复杂度(复杂度, 为项目增加了额外的复杂性):::otherNode
缺点 --> 降低了可读性(降低了可读性, 自动生成的选择器大大降低了代码的可读性):::otherNode
style CSS-in-JS fill:#F8840D,color:white,stroke:#F8840D
style 优点 fill:#52c41a,color:white,stroke:#52c41a
style 缺点 fill:#f5222d,color:white,stroke:#f5222d
classDef otherNode fill:#1890ff,color:white,stroke:#1890ff
总结
它特别适合在组件库中使用。
CSS-in-JS只是一种模式,需要框架的支持。
常用的框架有:
DISCUSSION
讨论与反馈