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

把問題的結論放在開頭,關于我的故事,感興趣的同學或者覺得會對自己有幫助的同學慢慢欣賞吧,這樣可以節省另外部分同學的時間。

1. css-modules是什么?

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

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

當項目經由多位技術背景和水平參差不齊的開發者接手過后,項目的樣式已經不能乖乖的被后面的同學搞了,不斷的重構重構重構...... 嗯,是時候要有人拿小皮鞭來規范開發秩序了。css-modules的出現解決了全局樣式污染,龐大的頁面dom節點取名字的問題。

3. css-modules的科學實踐

組件容器內樣式作用域弱約束,頁面區域間作用域強隔離。
例如頁面結構為 header、main、aside、footer 這四個區域。header和aside共同使用了Navbar組件,Navbar的組件是復用了,樣式一致,但是在header和aside中要有兩種視覺效果。這時候把header和aside可以分別看做Navbar的兩個實例容器,header和aside是用css-module管理的local作用域,在他們的local作用域中聲明一個global作用域,通過.header :global .nav-bar{...}的方式覆寫組件樣式,實現同一組件在同一頁面不同區域的樣式自定義。

4. 對css-modules出現背景所做的反思

css對于專業前端來說是很熟悉的,通過命名前綴,結構化命名來描述頁面結構。但這些都是人為經驗去做的代碼管理,在團隊開發資源緊張的情況下,很多不熟悉css的后端同學也需要盡快完成前端的任務,導致大量的樣式沖突和冗余。于是乎,標準化組件給大家更少的選擇,更少的關注css...

當然以上是出于許許多多后端、客戶端發者對web前端的理解基礎上給出的解決方案。語言之間的思想是會互相影響的,就那這個模塊化的方案結合es6來說,我感覺就很像python了。

下面是關于我對css-modules使用經歷的小故事:

不久前換了工作,開始使用React來開發web。早先就聽聞過React的大名,之前的工作是團隊中就我一只前端,考慮到效率問題,工作中一直在用Angular 1.X 來霸道的進行開發,功能大而全,即使是一個人來同時做前后端,也可以很快的開發出可維護性的系統。那么現在開始用了React,初次的開發體驗我選擇了"ant-design"。

根據ant-design的快速上手教程,我搭建起來一個初始化的項目結構。但是當我需要按照設計圖去還原視覺效果的時候,我懵逼了。jsx的語法,加上模塊化的React組件,在開發界面功能的時候很方便,有種類似客戶端的控件引入方式。不過在我需要按照視覺設計圖去覆寫組件樣式的時候,我發現竟然沒有對應的css樣式!

經過調試發現,項目結構中引入了css-modules,在瀏覽器的開發者工具中會看到,頁面中節點的className被加上了hash字符串,這也就意味著css有了作用域的概念。后來查css-modules的文檔,如果是全局作用域的樣式需要在樣式前面包一層 :global,代碼如下:

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

在沒有:global包裹的樣式,編譯后的結果是一下這種:
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樣式生效,必須在對應的節點使用 "module.style"(模
塊.樣式屬性)的方式綁定樣式。這里就沒辦法通過外部容器的選擇器來定位組件節點了。因為組件是在自定義渲染部分引入使用,組件節點是自動渲染的,如果組件沒有開放子節點的className字段,是無法修改組件樣式的。

不過,如果在組件沒有使用css-modules的情況下,我們可以通過在頁面節點-組件容器的css作用域來創建一個組件容器的全局作用域(該作用域存在于頁面節點的local作用域內,頁面其他區域的css作用域是隔離的),代碼如下:

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

在經過一陣驚訝和反思后,結合我之前的工作經歷不禁開始贊嘆css-modules的牛逼。
說他牛逼并不是因為他在技術上的實現有多么復雜,而是他可以讓項目的不確定性大大降低,代碼的可維護性得以提升。

以前也跟朋友吐槽過,相信前端同學有的也有過這樣的經歷,入職后發現自己是唯一的前端,而且接手的項目之前是后臺的同學開發的。素質高點的js不會亂引的太嚴重,然而大多數后臺的同學是不熟悉css的,樣式不僅冗余,而且很多因為優先級而相互覆蓋的問題。

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容

  • 最近學習到CSS的繼承屬性,正好看到這篇文章,便將它翻譯出來。作者的思想,在平時的項目中或多或少都有用過,但是從來...
    hershin閱讀 952評論 0 1
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,661評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,151評論 4 61
  • 有一段時間很極端,覺得不應該隨便給人貼標簽,尤其愛說,不要給孩子隨便貼標簽。 隨著認知的變化,更加理性。 家長不給...
    信時光閱讀 155評論 0 0
  • 夜色溫柔,是在一個人內心溫柔,感動了自己,用無限柔情和寬容去看待周圍的一切的時候。 它也許是晚歸時,公交車窗外滑過...
    會游走的魚閱讀 856評論 0 0