CSS也有作用域奕锌?—"css-modules"說它為什么要這么做!

把問題的結(jié)論放在開頭村生,關(guān)于我的故事惊暴,感興趣的同學(xué)或者覺得會對自己有幫助的同學(xué)慢慢欣賞吧,這樣可以節(jié)省另外部分同學(xué)的時間趁桃。

1. css-modules是什么辽话?

css-modules是將css賦予作用域概念的一種樣式模塊化解決方案。通過給樣式名加hash字符串后綴的方式卫病,實現(xiàn)特定作用域語境中的樣式編譯后的樣式在全局唯一油啤。

2. css-modules解決了什么問題?

當(dāng)項目經(jīng)由多位技術(shù)背景和水平參差不齊的開發(fā)者接手過后蟀苛,項目的樣式已經(jīng)不能乖乖的被后面的同學(xué)搞了益咬,不斷的重構(gòu)重構(gòu)重構(gòu)...... 嗯,是時候要有人拿小皮鞭來規(guī)范開發(fā)秩序了屹逛。css-modules的出現(xiàn)解決了全局樣式污染础废,龐大的頁面dom節(jié)點取名字的問題汛骂。

3. css-modules的科學(xué)實踐

組件容器內(nèi)樣式作用域弱約束,頁面區(qū)域間作用域強(qiáng)隔離评腺。
例如頁面結(jié)構(gòu)為 header帘瞭、main、aside蒿讥、footer 這四個區(qū)域蝶念。header和aside共同使用了Navbar組件,Navbar的組件是復(fù)用了芋绸,樣式一致媒殉,但是在header和aside中要有兩種視覺效果。這時候把header和aside可以分別看做Navbar的兩個實例容器摔敛,header和aside是用css-module管理的local作用域廷蓉,在他們的local作用域中聲明一個global作用域,通過.header :global .nav-bar{...}的方式覆寫組件樣式马昙,實現(xiàn)同一組件在同一頁面不同區(qū)域的樣式自定義桃犬。

4. 對css-modules出現(xiàn)背景所做的反思

css對于專業(yè)前端來說是很熟悉的,通過命名前綴行楞,結(jié)構(gòu)化命名來描述頁面結(jié)構(gòu)攒暇。但這些都是人為經(jīng)驗去做的代碼管理,在團(tuán)隊開發(fā)資源緊張的情況下子房,很多不熟悉css的后端同學(xué)也需要盡快完成前端的任務(wù)形用,導(dǎo)致大量的樣式?jīng)_突和冗余。于是乎证杭,標(biāo)準(zhǔn)化組件給大家更少的選擇田度,更少的關(guān)注css...

當(dāng)然以上是出于許許多多后端、客戶端發(fā)者對web前端的理解基礎(chǔ)上給出的解決方案躯砰。語言之間的思想是會互相影響的每币,就那這個模塊化的方案結(jié)合es6來說,我感覺就很像python了琢歇。

下面是關(guān)于我對css-modules使用經(jīng)歷的小故事:

不久前換了工作兰怠,開始使用React來開發(fā)web。早先就聽聞過React的大名李茫,之前的工作是團(tuán)隊中就我一只前端揭保,考慮到效率問題,工作中一直在用Angular 1.X 來霸道的進(jìn)行開發(fā)魄宏,功能大而全秸侣,即使是一個人來同時做前后端,也可以很快的開發(fā)出可維護(hù)性的系統(tǒng)。那么現(xiàn)在開始用了React味榛,初次的開發(fā)體驗我選擇了"ant-design"椭坚。

根據(jù)ant-design的快速上手教程,我搭建起來一個初始化的項目結(jié)構(gòu)搏色。但是當(dāng)我需要按照設(shè)計圖去還原視覺效果的時候善茎,我懵逼了。jsx的語法频轿,加上模塊化的React組件垂涯,在開發(fā)界面功能的時候很方便,有種類似客戶端的控件引入方式航邢。不過在我需要按照視覺設(shè)計圖去覆寫組件樣式的時候耕赘,我發(fā)現(xiàn)竟然沒有對應(yīng)的css樣式!

經(jīng)過調(diào)試發(fā)現(xiàn)膳殷,項目結(jié)構(gòu)中引入了css-modules操骡,在瀏覽器的開發(fā)者工具中會看到,頁面中節(jié)點的className被加上了hash字符串赚窃,這也就意味著css有了作用域的概念当娱。后來查css-modules的文檔,如果是全局作用域的樣式需要在樣式前面包一層 :global考榨,代碼如下:

:global {  
  html, body, #root {    
    height: 100%;  
  }    
  body { background: #fafafa; }
}

在沒有:global包裹的樣式,編譯后的結(jié)果是一下這種:
MainLayout.less

.main{...}

index.html

<div id="root">
  <div class="main"></div>
</div>

編譯后的index.html

<div id="root">
  <div class="main___1gjAI"></div>
</div>

MainLayout.jsx

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { DatePicker, message } from 'antd';
import styles from './MainLayout.less';

ReactDOM.render(
  <div className={styles.main}>
    <DatePicker onChange={value => this.handleChange(value)} />
  </div>, 
  document.getElementById('root')
);

這里想要讓css樣式生效鹦倚,必須在對應(yīng)的節(jié)點使用 "module.style"(模
塊.樣式屬性)的方式綁定樣式河质。這里就沒辦法通過外部容器的選擇器來定位組件節(jié)點了。因為組件是在自定義渲染部分引入使用震叙,組件節(jié)點是自動渲染的掀鹅,如果組件沒有開放子節(jié)點的className字段,是無法修改組件樣式的媒楼。

不過乐尊,如果在組件沒有使用css-modules的情況下,我們可以通過在頁面節(jié)點-組件容器的css作用域來創(chuàng)建一個組件容器的全局作用域(該作用域存在于頁面節(jié)點的local作用域內(nèi)划址,頁面其他區(qū)域的css作用域是隔離的)扔嵌,代碼如下:

.main{
  :global{
    .ant-calendar-picker{
      /*這里可以覆寫 DatePicker組件的樣式了*/
    }  
  }
}

在經(jīng)過一陣驚訝和反思后,結(jié)合我之前的工作經(jīng)歷不禁開始贊嘆css-modules的牛逼夺颤。
說他牛逼并不是因為他在技術(shù)上的實現(xiàn)有多么復(fù)雜痢缎,而是他可以讓項目的不確定性大大降低,代碼的可維護(hù)性得以提升世澜。

以前也跟朋友吐槽過独旷,相信前端同學(xué)有的也有過這樣的經(jīng)歷,入職后發(fā)現(xiàn)自己是唯一的前端,而且接手的項目之前是后臺的同學(xué)開發(fā)的嵌洼。素質(zhì)高點的js不會亂引的太嚴(yán)重案疲,然而大多數(shù)后臺的同學(xué)是不熟悉css的,樣式不僅冗余麻养,而且很多因為優(yōu)先級而相互覆蓋的問題褐啡。

換個角度想想就發(fā)現(xiàn)了css-modules的價值,就是tmd讓不熟css的同學(xué)乖乖的不要給人家挖坑回溺。如果說真的需要接手這類的項目春贸,即便是損失了css的靈活性,我也是會開心的笑出眼淚吧(畢竟比反復(fù)重構(gòu)人家寫的頁面要好很多)遗遵。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末萍恕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子车要,更是在濱河造成了極大的恐慌允粤,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翼岁,死亡現(xiàn)場離奇詭異类垫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)琅坡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進(jìn)店門悉患,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人榆俺,你說我怎么就攤上這事售躁。” “怎么了茴晋?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵陪捷,是天一觀的道長。 經(jīng)常有香客問我诺擅,道長市袖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任烁涌,我火速辦了婚禮苍碟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撮执。我一直安慰自己驰怎,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布二打。 她就那樣靜靜地躺著县忌,像睡著了一般掂榔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上症杏,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天装获,我揣著相機(jī)與錄音,去河邊找鬼厉颤。 笑死穴豫,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逼友。 我是一名探鬼主播精肃,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼帜乞!你這毒婦竟也來了司抱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤黎烈,失蹤者是張志新(化名)和其女友劉穎习柠,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體照棋,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡资溃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了烈炭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溶锭。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖符隙,靈堂內(nèi)的尸體忽然破棺而出暖途,到底是詐尸還是另有隱情,我是刑警寧澤膏执,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站露久,受9級特大地震影響更米,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜毫痕,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一征峦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧消请,春花似錦栏笆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春针饥,著一層夾襖步出監(jiān)牢的瞬間厂抽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工丁眼, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留筷凤,地道東北人。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓苞七,卻偏偏與公主長得像藐守,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蹂风,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,647評論 2 354

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

  • 最近學(xué)習(xí)到CSS的繼承屬性硫眨,正好看到這篇文章足淆,便將它翻譯出來。作者的思想礁阁,在平時的項目中或多或少都有用過巧号,但是從來...
    hershin閱讀 939評論 0 1
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,082評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件姥闭、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,095評論 4 62
  • 有一段時間很極端丹鸿,覺得不應(yīng)該隨便給人貼標(biāo)簽,尤其愛說棚品,不要給孩子隨便貼標(biāo)簽靠欢。 隨著認(rèn)知的變化,更加理性铜跑。 家長不給...
    信時光閱讀 153評論 0 0
  • 夜色溫柔门怪,是在一個人內(nèi)心溫柔,感動了自己锅纺,用無限柔情和寬容去看待周圍的一切的時候掷空。 它也許是晚歸時,公交車窗外滑過...
    會游走的魚閱讀 846評論 0 0