前言
團隊在使用react時,不斷探索,使用了不少不一樣的css實現方式,此篇blog總結了,react項目中常見的幾種css解決方案:inline-style/radium/style-component,只列舉了團隊項目中用過的一下實現方式,還有其餘的不過多展開css
css的不足
樣式與狀態相關的狀況愈來愈多,須要動態、能直接訪問組件state的css。
一切樣式都是全局,產生的各類命名的痛苦,BEM等命名規則能解決一部分問題,但當你使用三方插件時卻沒法避免命名衝突。react
Vue怎麼解決
scoped 屬性
動態css的語法 v-bind class stylewebpack
react中使用css的標準
是否解決了React開發的痛點:局部css,動態css?
是否支持全部css甚至是sass用法?僞類,嵌套,動畫,媒體查詢?
是否兼容你須要使用的第三方UI庫?
是否能和純css,或者是其餘css框架很好共存,以備遇到特殊狀況能夠有方案B?
性能?大小?web
react 原生css
inline style數組
const textStyles = { color: 'white', backgroundColor: this.state.bgColor }; <p style={textStyles}>inline style</p>
缺點:瀏覽器
發明了一套新的 css-in-js 語法,使用駝峯化名稱等一些規則 不支持全部的 css,例如 media queries, browser states (:hover, :focus, :active) and modifiers (no more .btn-primary!). inline 寫法若是直接同行寫影響代碼閱讀,不清晰優雅
Radium
Features:
Conceptually simple extension of normal inline styles 原生css擴展,改良版
Browser state styles to support :hover, :focus, and :active 支持瀏覽器樣式
Media queries 支持媒體查詢
Automatic vendor prefixing 自動組件前綴 scope
Keyframes animation helper 寫動畫更方便,封裝Keyframes
ES6 class and createClass support 支持react類和createClass的寫法sass
簡單使用:babel
<Button kind="primary">Radium Button</Button> import Radium from 'radium'; import React from 'react'; import color from 'color'; class Button extends React.Component { static propTypes = { kind: PropTypes.oneOf(['primary', 'warning']).isRequired }; render() { return ( <button // 多個樣式使用數組方便合併 style={[ styles.base, styles[this.props.kind] ]}> {this.props.children} </button> ); } } // 使用了HOC的方式注入樣式 // Radium's primary job is to apply interactive or media query styles, but even // if you are not using any special styles, the higher order component will still: // Merge arrays of styles passed as the style attribute // Automatically vendor prefix the style object // Radium(config)(component) 還能夠傳入一些配置 Button = Radium(Button); var styles = { base: { color: '#fff', ':hover': { background: color('#0074d9').lighten(0.2).hexString() } }, primary: { background: '#0074D9' }, warning: { background: '#FF4136' } };
keyframes使用app
class Spinner extends React.Component { render () { return ( <div> <div style={styles.inner} /> </div> ); } } Spinner = Radium(Spinner); var pulseKeyframes = Radium.keyframes({ '0%': {width: '10%'}, '50%': {width: '50%'}, '100%': {width: '10%'}, }, 'pulse'); var styles = { inner: { // Use a placeholder animation name in `animation` animation: 'x 3s ease 0s infinite', // Assign the result of `keyframes` to `animationName` animationName: pulseKeyframes, background: 'blue', height: '4px', margin: '0 auto', } };
Css Modules
適用於全部使用 webpack 等打包工具的開發環境框架
{ loader: "css-loader", options: { importLoaders: 1, modules: true, localIdentName: "[name]__[local]___[hash:base64:5]" // 爲了生成類名不是純隨機 }, }, import styles from './table.css'; render () { return <div className={styles.table}> <div className={styles.row}> <div className={styles.cell}>A0</div> <div className={styles.cell}>B0</div> </div> </div>; } /* table.css */ .table {} .row {} .cell {}
缺點:
class名必須是駝峯形式,不然不能正常在js裏使用 styles.table 來引用 因爲css模塊化是默認,當你但願使用正常的全局css時,須要經過:local 和 :global 切換,不方便 全部的 className 都必須使用 {style.className} 的形式 寫在外部樣式文件中,沒法處理動態css
優化:
babel-plugin-react-css-modules 能夠照常寫 'table-size' 之類帶橫槓的類名 正常書寫字符串類名,不用加style前綴
// .bablerc { "plugins": [ ["react-css-modules", { // options }] ] }
缺點:
不過使用 styleName 遇到三方UI庫該怎麼辦呢
補充:
create-react-app v2 直接使用css-moudues和sass
使用方法爲一概將css文件命名爲 XXX.modules.css, 以上例,即爲 table.modules.css, 便可使用。這一解決法的優雅在於,全局的css能夠正常使用,只有帶.modules.css後綴的纔會被modules化
styled-components
使用 ES6 的模板字符串,在js文件裏寫純粹的css。
補充sass經常使用語法
變量:以$開頭/變量須要在字符串之中,在#{}之中
計算: 屬性可使用算式
嵌套: &引用父元素
繼承: @extend
重用: @mixin命令,定義一個代碼塊(能夠傳參數)/@include命令,調用這個mixin
引入文件: @import
// 變量 $blue : #1875e7; $side : left; div { color : $blue; } .rounded { border-#{$side}-radius: 5px; } // 計算 body { margin: (14px/2); top: 50px + 100px; right: $var * 10%; } // 嵌套 a { &:hover { color: #ffb3ff; } } // 繼承 .class1 { border: 1px solid #ddd; } .class2 { @extend .class1; font-size:120%; } // 重用 @mixin left($value: 10px) { float: left; margin-right: $value; } div { @include left(20px); } //引入外部文件 @import "path/filename.scss"