跳到主要内容

CSS-in-JS

· 阅读需 5 分钟

传统开发模式

一般而言,在 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?

以前的开发模式是页面,首页、列表页面、详情页面、使用link引入 CSS 到 HTML 中,CSS 是没有作用域的,所有整个 CSS 文件都会应用到到 HTML 中,很容易导致样式冲突。

现有的开发模式是组件,所以就期望只应用该组件本身的样式。CSS 代码只在组件范围中进行生效,组件与组件之间不产生冲突。在 React 实践中,我们已经把 HTML 以及 JavaScript 写在一起,变成一个个组件。如果采用CSS-in-JS方案。 HTML、CSS、JavaScript 都使用 JavaScript。

解决作用域问题

使用CSS-in-JS,就可以使用 JavaScript 作用域模拟 CSS 作用域,让 CSS 拥有独立的作用域,阻止 CSS 代码泄露到组件外部,防止样式冲突。只在组件内部生效。从而解决 CSS 无作用域的问题。

增加组件的独立性、可移植性

移动组件,我们可能会忘记样式文件,甚至不知道样式文件在哪里,使用CSS-in-JS,那么组件就是一个独立文件,我们移动组件本身就可以了。开箱即用,从而轻松创建松耦合的应用。

可重用性

只需要编写一次,可以在任何地方运行,不仅可以在同一个应用程序中重用组件,可以在使用相同框架构建的其他应用程序中重用组件

动态性

CSS 缺乏动态性,不能根据条件给某个元素添加样式,使用CSS-in-JS,根据 JavaScript 动态功能为元素动态添加样式。从而让复杂的逻辑也可以应用于样式规则,特别需要创建动态功能的负责 UI,它是理想的解决方案。

按需引入

随着业务量的增加,组件越来越庞大,因此需要按需引入,采用treeshaking方式,使用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只是一种模式,需要框架进行支持。

常用的框架有