【譯】react:css in js

注:原文作者是來自facebook的前端基礎(chǔ)設(shè)施團(tuán)隊的Christopher Chedeau。

大規(guī)模項目中面臨的css問題:

  • 全局命名空間
  • 依賴
  • 無用代碼移除
  • 壓縮
  • 共享常量
  • 定制化
  • 隔離

舉個Button的例子:

/* button.css */
.button{
    background: #f6f7f8 url(/images/button/background.png) repeat-x;
    border: 1px solid #cdced0;
    border-radius: 2px;
    box-shadow: 0 1px 1px rgba(0,0,0,0.05);
}

.button-depressed{
    background-color: #4e69a2;
    border-color:#c6c7ca;
    color:#5890ff;
}

以上我們設(shè)計了一個button,存在常態(tài)和按下狀態(tài)。

全局變量

在w3schools.com的JavaScript的最佳實踐中,建議避免使用全局變量。

w3c javascript 最佳實踐

對于我來說,在css中仍然存在全局變量是一件讓人瘋狂的事情。在js編程中,我們很早就知道全局變量是不好的實踐。
我們學(xué)習(xí)使用局部變量、自執(zhí)行函數(shù)、模塊化編程來解決全局變量的問題。
但是,在bootstrap的css中,存在超過600個的全局變量。
在Facebook,我們使用一種css擴(kuò)展來解決這個問題。

/* button.css */
.button/container{


/* dropdown.css */
.dropdown/container .button/container{

這種方式,只有在button.css文件中的button/container樣式才會參與build,如果視圖在dropdown.css中使用,它將不會參與build.

如果需要導(dǎo)出全局變量,可以采用以下寫法:

.button/container/public{


.dropdown/container .button/container/public{

調(diào)用部分:

/* button.css */
.button/container{

/* button.js */
<div className={cx('button/container')}>

因為button/container不是有效的classname,因此我們的調(diào)用方式需要發(fā)生變化,調(diào)用cx(class extension)來完成轉(zhuǎn)換。

依賴

/* button.css */
.button/container{
/* button.js */
requireCSS('button')
<div className={cx('button/container')}>

以前我們把css打包到一個獨立的文件中,現(xiàn)在我們把它們分割成一個個獨立的文件,分別引入依賴。
很久以來,我們一直要求開發(fā)者只引入需要的css文件。但是如果其他人引入了某個css文件,它依舊會存在。
現(xiàn)在我們有了cx,它會進(jìn)行靜態(tài)分析,可以自動注入。

無用代碼移除

因為cx是唯一生成樣式的方式,這樣我們可以解決最麻煩的問題:移除無用的代碼。

壓縮

通過cx可以最小化所有的classname,讓js和css文件更小。

共享常量

.button/container{
    /* keep in sync with button.js */
    padding:5px;

//Keep in sync with button.css
var buttonPadding=5;

很長一段時間,我們采用注釋或者命名約定的方式來共享常量。

現(xiàn)在我們引入了css變量。

/* button.css */
.button/container{
    padding:var(button-padding);
var buttonPadding = cssVar('button-padding');
$CSSVar = array(
    'button-padding' => 5,
);

由于facebook很多項目使用了php語言,所以我們在php中定義了css變量。

此時,我們依舊存在兩個沒有解決的問題:定制化和隔離。

css in js方案

這一刻我們等了很久...

/* button.js */
var styles = {
    container: {
        backgroud: '#f6f7f8 url(/images/button/background.png) repeat-x',
        border: '1px solid #cdced0',
        borderRadius: 2,
        boxShadow: '0 1px 1px rgba(0,0,0,0.05)'
    },
    depressed: {
        backgroundColor: '#4e69a2',
        borderColor: '#c6c7ca',
        color: '#5890ff'
    }
};

我們使用內(nèi)聯(lián)樣式來渲染

<div style={styles.container}>

內(nèi)聯(lián)樣式并沒有那么糟糕。
首先:我們依舊在一個獨立的文件中編寫樣式;
其次:style實際比class語義上更好;
最后:我們并沒有直接應(yīng)用style,而是通過React Virtual DOM。

前五個問題順利解決。

定制化

/* button.js */
propTypes:{
    isDepressed:React.PropTypes.bool,
    style:React.PropTypes.object,
},

<div style={m(
    styles.container,
    this.props.isDepressed && styles.depressed,
    this.props.style
)}>

于是,我們同時解決了后兩個問題。很明顯,當(dāng)在js中寫樣式,樣式中的class只會獨立出現(xiàn)相互隔離。

結(jié)論

我并不是要說服你們拋棄css,使用js。
我們有了大量的css庫,例如less、sass...但是他們都沒有解決上面的7大問題。
css也并不是web中存在底層缺陷的唯一部分,但是React在嘗試解決他們中的一些問題。
我希望你們打破天花板,面對搭建web服務(wù)面臨的困境,去思考、討論并解決。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補...
    _Yfling閱讀 14,095評論 1 92
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,790評論 25 709
  • 我沒有堅持,每天來湖邊晨練,就是想來享受此刻的美好。 在我分享時間管理的經(jīng)驗時,每天跟我一起晨練瑜伽的茵,輕輕道出...
    袁一今閱讀 977評論 0 4
  • 之所以喜歡摩客原型推廣,主要在于簡單、安全(摩客有40萬用戶,當(dāng)然信任),和Mockplus一樣,簡單高效。 摩客...
    AC不是米蘭閱讀 363評論 2 1
  • 一:舊有模式 距離我決定的再次辟谷開始還有四天,如果今天不算那就是三天了,意味著明天是我們最后一天招募!突然心中感...
    潘存英閱讀 755評論 0 3

友情鏈接更多精彩內(nèi)容