css 的弱化与 js 的强化(转)
web
的三要素 html, css, js
在前端组件化的过程中,比如 react、vue 等组件化框架的运用,使 html 的弱化与 js 的强化
成为了一种趋势,而在这个过程中,其实还有另一种趋势也在慢慢形成:css 的弱化与 js 的强化
。
之前有写过一篇 CSS 模块化,但对 css in js
这种理念没有过多讲解,所以这次深入一下。
css in js
理念,即是摒弃原有的用 .css
文件书写样式,而把样式写进 js
里面,这样就可以做到一个组件对应一个文件、一个文件便是一个组件。
1. 支持的第三方库
- styled-components: 仅支持
react
- radium: 仅支持
react
- emotion
- aphrodite
- polished
- jss
- glamorous: 仅支持
react
- styled-jsx: 仅支持
react
- glamor: 仅支持
react
- styletron: 仅支持
react
更多第三方库可以参考 css-in-js。
2. 书写方式
一般 css in js
的写法有两种:
- 使用
es6
的模板字符串 - 使用 js 对象
{}
2.1 使用 es6
的模板字符串
styled-components、emotion、styled-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 对象 {}
radium、aphrodite、polished、jss、glamorous、glamor、styletron 都是采用的这种写法。
比如 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