React: CSS in JS,这个PPT是2014年11月一个Facebook的员工发布的PPT。一切都从这个PPT说起。
在这个PPT中,作者首先列举出了CSS目前面临的一些问题:
接着作者说了Facebook是如何解决这个问题的,Facebook通过扩展CSS语法,在class name中引入“包”的概念,编译工具会将这个包含了报名的class name进行编译,得到最终的class name。因为代码中无法知道最终的class name,所以需要通过cs这个工具函数来进行映射。通过这种hack方法,解决了他列出的7个问题。
但是,不完美。
最后,他提出了Facebook目前正在使用的技术:CSS IN JS。完全使用JS来写CSS:
像写普通的Javascript Object一样,书写带有层次结构的CSS。同时使用React的style书写来赋予这个对象。对象中的样式会被编译为这个DOM节点的InLine Style。
以为使用JS书写,所以前五点问题都自然而然地解决了:
而且还可以利用其它JS的特性,比如更具条件决定样式,比如支持从外部传入样式等!
类库
Facebook这个PPT发出来之后,社区沸腾了。因为这个PPT只是提出了一个大致的方向,一些细节上的问题并没有解决,比如模式的CSS IN JS是无法支持伪类和媒体查询的。所以一时之间,社区冒出了十几个基于这个思想的工具库。
React: CSS in JS techniques comparison这个项目对十几个css-in-js类库进行了特性对比。我们可以从中进行选择。
目前我的选择是:Radium
Radium
Radium是一个React样式工具库。主要是对伪类和媒体查询的支持。
看个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| // 引入Radium var Radium = require('radium'); var React = require('react'); var color = require('color');
// 使用Radium装饰器 @Radium class Button extends React.Component { static propTypes = { kind: React.PropTypes.oneOf(['primary', 'warning']).isRequired };
render() { // Radium扩展了React的style属性,支持传入一个数组。Radium会按顺序合并这些样式 // 这个特性很有用,可以根据条件合并一些即时的样式,比如结合props或者state return ( <button style={[ styles.base, styles[this.props.kind] ]}> {this.props.children} </button> ); } }
// 样式就是普通的object var styles = { base: { color: '#fff',
// 添加:hover伪类,是不是不能再简单了。。。 // 可以使用:hover, :focus, :active, or @media ':hover': { background: color('#0074d9').lighten(0.2).hexString() } },
primary: { background: '#0074D9' },
warning: { background: '#FF4136' } };
|
这个例子基本上说完了Radium的核心用法。就是使用Radium修饰器,使React注解支持扩展语法的style对象。如果不支持修饰器,也可以用函数的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // For ES6 and ES7 @Radium class Button extends React.Component { // ... }
// or class Button extends React.Component { // ... } module.exports = Radium(Button);
// or class Button extends React.Component { // ... } Button = Radium(Button);
|
参考资料