如果你用组件化的前端方案,比如React这种,那么毫无疑问,css in js方案要比传统的css方案要好。
css in js 有两点不可撼动的优越性。
1. 你不需要再为命名的css的 class name而思考了。传统的css方案,因为class name是全局的,你就要保证它的唯一性,你要把你的组件名等各种namespace作为class name的前缀,以保证唯一性。css in js主要是解决了这一点。
2. css直接使用js的变量。css是不能定义变量的,如果你使用less或者sass,确实可以定义变量,但那主要是为了共享,是没有办法使用js的变量的。这一点问题不大,不用js变量也能写的好好的,只是稍微麻烦一点。
从第一点出发,看看我所希望css in js是什么样的。然后再去看styled-component, emotion和jss是怎么做的,最后再去评价。
// button.css .my-button { background-color: withe; }
import './button.css' const App = props => { return <div css="my-button"></div> }
首先是一个css样式,和正常的css一样。然后用的时候把css的class name放到css(或者其他一个property)里面。渲染的结果里面并不包含my-button,而是一个生成的唯一的class name。
这种写法用法上和传统的css写法基本一样。
当然这只是我期待的css in js,应该是不存在这种开源代码的。理论上能不能实现我也不清楚,能想到的是写个babel loader去搞,但是对babel loader具体的职责我并不懂。
前面说了,这只是基于第一点而期待的,如果再加上第二点,那么简单这么做是不行的,因为上面本质上还是用的css样式,没办法吧把js变量放进去。
styled-component的做法:
const Button = styled.div` background-color: white; ` const App = props => { return <Button /> }
应该说这个脑洞非常大,直接把css作为了一个组件,而不是一个属性(className,style,css等等)。
emotion的做法:
const App = props => { return <div className={css` background-color: white; `}></div> }
这其实就是在代替内联样式。
或者这样:
const App = props => { return <div css={{backgroundColor: 'white'}}></div> }
而如果你用react自带的话,只是把上面的css换成style
const App = props => { return <div style={{backgroundColor: 'white'}}></div> }
当然渲染结果是有区别的,react自带的是内联样式,emotion渲染的是class 样式。
可以猜出来,emotion的初衷就是为了消灭内联样式。
jss的做法
const useStyles = createUseStyles({ backgroundColor: 'white', }) const App = props => { const { backgroundColor } = useStyles(); return <div className={backgroundColor}></div> }
和emotion的css方案差不多,具体样式都是用的js语法(backgroundColor: 'white',),而不是css语法(background-color: white;)。
区别是官方样例的倾向问题。jss更倾向于把一个组件内的所有css作为一个整体(当然你也可以分成多个useStyles)。
事实上jss和emotion用法基本是一样的,你用emotion同样可以把组件的css作为一个整体去定义。
我自己的倾向
styled-component是反人类的设计。原因是它会造成Component的混乱不堪,代码难以阅读,至少在react中用是这样。你没有办法非常容易的区分一个styled component和正常的Component,这样在读代码的时候就要思考它到底是什么。
emotion和jss上面分析了,区别不大。jss好像不支持css的语法方案?(事实上比较流行的几个css in js方案基本都是互通的。象jss和emotion都可以象styled-component那样去写)。
只是jss的文档更好一点。emotion的文档是匪夷所思的,把代码象内联样式一样去写???WTF!