css 的弱化与 js 的强化,转

web 的三要素 html, css, js 在前端组件化的过程中,比如 reactvue 等组件化框架的运用,使 html 的弱化与 js 的强化 成为了一种趋势,而在这个过程中,其实还有另一种趋势也在慢慢形成:css 的弱化与 js 的强化

之前有写过一篇 CSS 模块化,但对 css in js 这种理念没有过多讲解,所以这次深入一下。

css in js 理念,即是摒弃原有的用 .css 文件书写样式,而把样式写进 js 里面,这样就可以做到一个组件对应一个文件、一个文件便是一个组件。

1. 支持的第三方库

  1. styled-components: 仅支持 react
  2. radium: 仅支持 react
  3. emotion
  4. aphrodite
  5. polished
  6. jss
  7. glamorous: 仅支持 react
  8. styled-jsx: 仅支持 react
  9. glamor: 仅支持 react
  10. styletron: 仅支持 react

更多第三方库可以参考 css-in-js

2. 书写方式

一般 css in js 的写法有两种:

  1. 使用 es6 的模板字符串
  2. 使用 js 对象 {}

2.1 使用 es6 的模板字符串

styled-componentsemotionstyled-jsx 都是采用的这种写法。

比如 styled-components:

 1 import React from 'react';
 2 import styled from 'styled-components';
 3 
 4 // 创建一个使用 <h1> 标签的 <Title> React 组件
 5 const Title = styled.h1`
 6   font-size: 1.5em;
 7   text-align: center;
 8   color: palevioletred;
 9 `;
10 
11 // 创建一个使用 <section> 标签的 <Wrapper> React 组件
12 const Wrapper = styled.section`
13   padding: 4em;
14   background: papayawhip;
15 `;
16 
17 // 就像正常的 React 组件一样,只不过他们都自带样式
18 <Wrapper>
19   <Title>Hello World, this is my first styled component!</Title>
20 </Wrapper>

比如 emotion:

1 import { css } from 'emotion';
2 
3 const app = document.getElementById('root');
4 const myStyle = css`
5   color: rebeccapurple;
6 `;
7 app.classList.add(myStyle);

2.2 使用 js 对象 {}

radiumaphroditepolishedjssglamorousglamorstyletron 都是采用的这种写法。

比如 radium:

 1 import Radium from 'radium';
 2 import React from 'react';
 3 import color from 'color';
 4 
 5 var styles = {
 6   base: {
 7     color: '#fff',
 8     ':hover': {
 9       background: color('#0074d9').lighten(0.2).hexString()
10     }
11   },
12   primary: {
13     background: '#0074D9'
14   },
15   warning: {
16     background: '#FF4136'
17   }
18 };
19 
20 class Button extends React.Component {
21   render() {
22     return (
23       <button
24         style={[styles.base, styles[this.props.kind]]}>
25         {this.props.children}
26       </button>
27     );
28   }
29 }
30 
31 Button = Radium(Button);
32 
33 <Button kind="primary">Primary</Button>
34 <Button kind="warning">Warning</Button>

比如 aphrodite:

 1 import React, { Component } from 'react';
 2 import { StyleSheet, css } from 'aphrodite';
 3 
 4 const styles = StyleSheet.create({
 5   red: {
 6     backgroundColor: 'red'
 7   },
 8   blue: {
 9     backgroundColor: 'blue'
10   },
11   hover: {
12     ':hover': {
13       backgroundColor: 'red'
14     }
15   },
16   small: {
17     '@media (max-width: 600px)': {
18       backgroundColor: 'red',
19     }
20   }
21 });
22 
23 class App extends Component {
24   render() {
25     return <div>
26       <span className={css(styles.red)}>
27         This is red.
28       </span>
29       <span className={css(styles.hover)}>
30         This turns red on hover.
31       </span>
32       <span className={css(styles.small)}>
33         This turns red when the browser is less than 600px width.
34       </span>
35       <span className={css(styles.red, styles.blue)}>
36         This is blue.
37       </span>
38       <span className={css(styles.blue, styles.small)}>
39         This is blue and turns red when the browser is less than 600px width.
40       </span>
41     </div>;
42     }
43 }

这种写法的好处是,不需要 es6 的语法,对属性可以更方便的操作。

3. 决定是否使用

如果你是喜欢把样式和组件分开书写,那么这种方式就可能不太适合你;如果你追求一个组件对应一个文件、一个文件便是一个组件,那就立马用上吧。

4. 后续

转载自 https://segmentfault.com/a/1190000016422897