用 styled-components 在 react 中編寫 css

這么久以來,各種各樣的框架試圖讓 web 組件化穴亏。到目前為止蜂挪,react 基本做到了這一點:用一個自定義標(biāo)簽的方式組織 html 在一起。

<Wrapper>
    <Header />
    <ProductList />
    <Footer />
</Wrapper>

上面的這種寫法在傳統(tǒng)的 web 開發(fā)中真是不敢想象嗓化,然而在 react 中的確實現(xiàn)了棠涮。如果你使用 create-react-app 這樣的腳手架工具,你可以快速的搭建起來這樣的體系刺覆。然而严肪,即便是這樣子,web 組件化依然有一個點沒有解決:如何將樣式和組件綁定在一起。當(dāng)然驳糯,試圖解決這個問題的工具有很多篇梭,也有很多人不認(rèn)為這是一個問題。我在這里試圖解釋一些觀點酝枢,并闡述為什么我覺得用 styled-components 可以在一定程度上解決一系列問題恬偷。

寫 css 的最佳方式

目前,react 陣營對寫 css 這個問題有兩個陣營帘睦。一個陣營表示 css 應(yīng)當(dāng)和 js 寫在一起袍患,而另一個陣營則認(rèn)為 css 原本是可以和 js 分離的。我們在這里做一個簡單的例子竣付。

首先是 css in js 的例子:

const style = {
    margin: "1em 2em",
    color: "gray",
    background-color: "white"
};

const StyledDiv = (props) => {
    return <div style={style}>A test</div>
};

而 css 和 js 分離就很簡單了:


.styled-div {
    margin: 1em 2em;
    color: gray;
    background-color: white;    
}

import "./StyledDiv.css";

const StyledDiv = (props) => {
    return <div className="styled-div">A test</div>
};

當(dāng)然诡延,這里展示的 css in js 只是一種非常原始的方式:用 object 直接將 style 注入到組件中古胆。這樣做的好處有兩個:

  1. css 不在是全局的了,style 的生命周期與生命范圍終于和 component 一致了赤兴,那么因為全局變量導(dǎo)致的可怕的為何災(zāi)難緩解了
  2. 在組件內(nèi)對樣式的操縱可以直接進(jìn)行,無需通過 className 處理桶良,當(dāng)然也避免了創(chuàng)建全局的 className 了

可以看到,這里基本上就是以解決 css 的全局性為出發(fā)點的陨帆。

而 css 和 js 的分離當(dāng)然也有其天然的優(yōu)勢:

  1. 可以用 css 的方式寫 css,css 選擇器隨便用
  2. 我還可以加各種 preprocessor 和 post processor疲牵,比如寫 scss 比如加 auto-prefix

對我來說,用 object 的方式去寫 css 體驗實在是太差了纲爸。而且作為 csscascade,如果不能用多級的選擇器去定位 css 而是在一層層的 html 元素中添加樣式簡直就是噩夢识啦。我不覺得這樣的可維護(hù)水平比全局 css 要高...所以我覺得如果能把兩者的優(yōu)勢結(jié)合在一起,就應(yīng)該是一個可以被更多人介紹的方式:

  1. 用 css 的語法寫 css
  2. 能創(chuàng)建局部 className
  3. 支持 preprocessor 和 postprocessor

那么在這里就不得不提另外一個有意思的東西:css-modules颓哮。它的主要思想是通過為 css 生成隨機的類名稱的方式來建立一種局部類命名的方式。

styled-components 基本上集成了這個工作冕茅,并在此基礎(chǔ)上基本實現(xiàn)了以上的三點要求蛹找。

const Summary = styled.div`
  margin-top: 2em;
  text-align: right;

  .price {
    color: #ff0036;
    font-size: 1.2em;
  }

  &> * {
    display: inline-block;
    margin-left: 1em;
  }
`;
  1. Summary 的 css 是以 css 的方式編寫的,支持多層次的定義
  2. styled-components 會把上面定義的 css 以一個特別的 className 的方式注入到元素上庸疾,實現(xiàn)了局部類定義
  3. styled-components 支持了基本的類似于 scss 的嵌套語法(還支持 extend 語法,這里并沒有展示)彼硫,并且內(nèi)嵌了 autoprefix 的模塊

我最近開始在一個項目上使用它炊豪,整體來說還是感覺不錯。

兼容現(xiàn)在已有的 react components 和 css 框架

styled-components 采用的 css-module 的模式有另外一個好處就是可以很好的與其他的主題庫進(jìn)行兼容词渤。因為大部分的 css 框架或者 css 主題都是以 className 的方式進(jìn)行樣式處理的,額外的 className 和主題的 className 并不會有太大的沖突缺虐。你可以認(rèn)為這是一個應(yīng)當(dāng)使用全局 css 的地方(所以我并不贊成用 styled-components 里面的 theming 接口去做這件事)。相對于以 object 的方式寫 style 的 material-ui 真是好太多了高氮,看看 material-ui 講述如何進(jìn)行樣式自定義就知道這并不是一個很成熟的想:

  1. css 內(nèi)嵌到組建里影響了組件自身結(jié)構(gòu)的表現(xiàn)
  2. inline style 意味著最高的優(yōu)先級,其無法和其他的主題庫配合

styled-components 的語法同樣支持對一個 React 組件進(jìn)行擴展:

const StyledDiv = styled(Row)`
  position: relative;
  height: 100%;
  .image img {
    width: 100%;
  }
  .content {
    min-height: 30em;
    overflow: auto;
  }
  .content h2 {
    font-size: 1.8em;
    color: black;
    margin-bottom: 1em;
  }
`;

這里我把 ant design 做為我默認(rèn)的樣式庫剪芍,在其基礎(chǔ)上我對其一些元素做了增強。兩者可以很好的在一起使用罪裹。

這里符一個 github 項目 里面包含了很多使用 styled-components 的例子。

相關(guān)資料

  1. scss
  2. js in css
  3. styled components
  4. auto-prefix
  5. material-ui
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末套耕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子峡继,更是在濱河造成了極大的恐慌,老刑警劉巖碾牌,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異小染,居然都是意外死亡,警方通過查閱死者的電腦和手機裤翩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門调榄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呵扛,“玉大人,你說我怎么就攤上這事今穿$土椋” “怎么了蓝晒?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長胚嘲。 經(jīng)常有香客問我,道長馋劈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任妓雾,我火速辦了婚禮,結(jié)果婚禮上垒迂,老公的妹妹穿的比我還像新娘。我一直安慰自己娇斑,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布唯竹。 她就那樣靜靜地躺著,像睡著了一般苦丁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旺拉,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音晋涣,去河邊找鬼。 笑死沉桌,一個胖子當(dāng)著我的面吹牛算吩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播佃扼,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼压昼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起窍霞,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤尽超,失蹤者是張志新(化名)和其女友劉穎官撼,沒想到半個月后似谁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掠哥,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年塞琼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彪杉。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡牵咙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出洁桌,到底是詐尸還是另有隱情渴丸,我是刑警寧澤另凌,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站吠谢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏工坊。R本人自食惡果不足惜错沃,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枢析。 院中可真熱鬧,春花似錦刃麸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吁伺。三九已至,卻和暖如春篮奄,著一層夾襖步出監(jiān)牢的瞬間捆愁,已是汗流浹背窟却。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留夸赫,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓茬腿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親切平。 傳聞我的和親對象是個殘疾皇子握础,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,077評論 25 707
  • 原文地址:react-css-modules閱讀本文前建議了解 CSS Modules 的知識弓候。墻裂推薦閱讀 Ca...
    梁相輝閱讀 2,271評論 1 18
  • 是一句還是一萬句邦蜜? By/夭夭 沒有神的世界里,人只能一輩子都在尋找悼沈,尋找一個人贱迟,和他說一句知心的話,一個人內(nèi)心的...
    李珩玉閱讀 276評論 0 0
  • 周末上完舞蹈課衣吠,幾個小小朋友聚集在體育館的廣場玩,朵朵上一年級了缚俏,學(xué)會了輪滑,四個小姑娘輪流穿著她的輪滑鞋忧换,每個小...
    喜歡小草閱讀 204評論 0 0
  • 今天早上我們?nèi)コ宰灾汀9吆玫目ㄔ谖业陌镅遣纾允俏宜⒌目ǎ⑼昕ㄊ切枰炞值纳卜欤呛炞值臅r候我根本沒有看單子上...
    張續(xù)飛閱讀 171評論 0 0