CSS-in-JS的工具库让我们可以以一种新的方式来写css,支持动态函数、css作用域并且可移植。但是对于开发者来说,这会使得前端开发的复杂性更高,是否值得使用是具有争议的。这篇本章主要是为了让你从更高的层面去了解CSS-in-JS工具库,从原理上来看它们解决了什么问题,以及在项目中该不该使用它们。
什么是CSS-in-JS
前端主流框架React、Vue、Angular都是基于组件开发的,因此组件化开发也是主流的前端开发方式。一个组件通常是像按钮button、弹窗pop-up、导航栏这样的一个UI元素,只需要实现一次即可在应用的各个场景中使用,我们的整个单页面应用(SPA)可以由一个个组件来组成。然而,如何很好的组织SPA应用中各个组件的样式是一个难题。如果使用全局CSS文件,CSS文件中的样式会相互覆盖,导致写的样式可能不生效,使得最后展示的页面与预期的不符。对于有样式SPA应用,依赖难以管理,使得模块化的网页应用的复杂性不可预测。使用CSS-in-JS,可以让每个打包后的组件包含它所有的样式和依赖,在不依赖任何外部css文件的情况下正常工作。styled-components作者之一Max Soiber在他的博客中有写道CSS-in-JS的工作原理:
For three years, I have styled my web apps without any .css files. Instead, I have written all the CSS in JavaScript. ... I can add, change and delete CSS without any unexpected consequences. My changes to the styling of a component will not affect anything else. If I delete a component, I delete its CSS too. No more append-only stylesheets!
翻译过来:
我已经三年没有在我的网页应用中写一个css文件,所有的css都写在js代码中… 我可以毫无顾虑的添加、改变和删除css样式,对于某个组件样式的修改不会产生任何副作用。删除一个组件的同时也删除了它的CSS,不再需要使用追加属性的方式写样式。
由此看来,CSS-in-JS的核心其实就是在把CSS写在JS中,这样js模块化的同时css也实现了模块化。
常见的CSS-in-JS库
虽然说各种CSS-in-JS库的目的都是为了使得打包的组件中包含自己的样式,但是它们的特性和语法上还是有些许不同的。
基于框架
有些库只有在指定的框架下才能使用,比如radium只能用于React应用;styled-jsx只能用于jsx组件。基于框架CSS-in-JS库使用和框架相同的语法,比如styled-jsx在jsx中使用模版字符串的方式给组件添加css样式。下面是使用styled-jsx(github文档地址)创建的常规尺寸和大尺寸两种按钮:
const
Button
=
(
props
)
=>
(
<
button className
={
'large'
in props
&&
'large'