在這個前端發展突飛猛進的世界,可以找到有所影響的概念至關困難,而將其準確無誤的傳達,讓人們願意嘗試,更是難上加難。css
拿CSS來看,在咱們寫CSS時,工具側最大的變化,也就是CSS處理器的使用,如:可能公認最好的SASS。還有PostCSS,提供了另外一種不一樣的解決方案,但也相差不大,屬於同種東西,都是輸入瀏覽器不支持的語法,而後輸出瀏覽器支持的語法。(這裏和以前的文章認識不一樣能夠點擊《PostCSS的認識誤區》查看詳細)html
如今,引入了CSS模塊的概念。本文,將介紹這方面的技術,會講到這種技術的幾點,而且會告訴你怎麼使用它。前端
官方定義:react
A CSS Module is a CSS file in which all class names and animation names are scoped locally by default.webpack
一個CSS模塊就是一個CSS文件,這個文件包含的全部類名和動畫名默認都是局部做用域的。git
實際比上面講的要複雜一些,類名默認是局部做用域的,這涉及到一些配置,一個構建過程和一些很難把握的東西。github
最終咱們把CSS模塊定義爲一種把相關CSS代碼組織成組件,並避免命名衝突的方法。(不用爲你組件的命名擔憂,在構建的過程當中會自動生成)。web
CSS模塊要放到構建過程當中處理,它自己並不作什麼。這看上去像是webpack或browserify的插件。它的工做原理是:當你在js模塊裏調用CSS模塊時(好比:React組件),CSS模塊將根據文件中動態做用域或命名空間裏的類名, 聲明一個對象字面量,字面量中的類名將被js以字符串的形式調用。chrome
讓咱們用一個例子來講明。npm
建一個簡單的CSS文件,.base類不是項目中惟一的,它不是做爲實際的類名來使用的。它至關於樣式裏的一個別名,這個別名將在js模塊中使用。
.base { color: deeppink; max-width: 42em; margin: 0 auto;}
這裏看一下,怎麼在JS組件中使用。
import styles from './styles.css'; element.innerHTML = `<div class="${styles.base}"> CSS Modules are fun. </div>`;
以上代碼會生成下面這樣的代碼(使用webpack構建工具的默認配置):
<div class="_20WEds96_Ee1ra54-24ePy">CSS Modules are fun.</div>
._20WEds96_Ee1ra54-24ePy { color: deeppink; max-width: 42em; margin: 0 auto;}
類名,能夠經過配置把類名加上特殊前綴,或使用短命名,但這並非重點(雖然短命名,表明着更少的CSS樣式)。
重點是指出,類名是動態生成的,惟一的,而且和樣式表正確映射的。
上面講了它是如何工做的。如今你內心必定有疑惑,下面讓咱們一一解決。
類名又不是爲了漂亮。它存在的目的是把樣式應用到元素上,因此這並不值得關注。
只是是要經過構建過程生成的代碼,調試起來都不容易。Sass也不容易調試,但可使用sourcemap,css模塊也能夠。實際上儘可能類名是生成的,但根據模塊裏的具體樣式調試並不難。若是你知道你正在調試的是哪一個模塊,你就能夠去對應模塊找到對應的樣式了。
重用性是沒錯的,但CSS模塊的目的就是把樣式組件化,清除全局的衝突和依賴。
另外,你也能夠定義全局的類(用:global()),好比一些公用的樣式。這些類名也是能夠在js組件中調用的
:global(.clearfix::after) { content: ''; clear: both; display: table;}
CSS模塊也能夠像SASS的@extend同樣,經過存在的模塊來擴展。不是直接複製一份樣式過來,而是對各選擇器樣式進行合併。
.base { composes: appearance from '../AnoherModule/styles.css';}
這和SASS編譯.scss文件爲正確的CSS樣式,PostCSS把樣式處理爲瀏覽器兼容的代碼同樣。既然已經使用了構建工具,這點也不用多想了。
由於不肯定將來的CSS模塊是否是如今這樣的,但這必定是樣式書寫的方向。大型網站使用的大量的全局樣式,不適合分解成小的組件。
全局惟一的CSS名,既強大又脆弱。不管是CSS模塊仍是之後其它工具。都須要找到既能夠具有全局樣式的公用,又能夠避免同做用域下樣式的命名衝突的解決方案。
上面提到了,使用CSS模塊須要webpack或browserify來構建。
使用webpack,先修改webpack.config.js文件,添加如下配置項,開啓CSS模塊功能。
{ test: /\.css$/, loader: 'style-loader!css-loader?modules'}
以上配置會在你的頁面插件<style>標籤。這裏須要一個webpack的extract text插件來去掉這個標籤
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules')}
使用Browserify,直接用命令行,代碼參數有點多。可使用npm來運行命令,配置一下package.json文件,代碼以下:
{ "scripts": { "build": "browserify -p [ css-modulesify -o dist/main.css ] -o dist/index.js src/index.js" }}
解釋一下,運行npm build,就至關於調用build對應的相關命令。處理src/index.js生成爲dist/index.js,並經過css-modulesify插件編譯dist/main.css樣式。若是想經過Autoprefixer插件添加瀏覽器前綴,命令可改爲下面這樣:
{ "scripts": { "build": "browserify -p [ css-modulesify --after autoprefixer -o dist/main.css ] -o dist/index.js src/index.js" }}
--after 在編譯完樣式後再運行autoprefixer插件。
如今,CSS模塊系統的生態圈還過小,但我相信,隨着愈來愈多的人認識到,這是適應於從小到大項目的解決方案,它會發展得愈來愈好。
CSS模塊化思想是正確的路。我也不是說本文介紹的方法,就是最好的解決方案,但已經能夠把CSS書寫得,具有如下特徵:模塊化,做用域或可重用。
想了解更多相關信息,可參閱CSS模塊項目建立人,Glen Maddern的《css模塊-將來的編碼方式》的文章。
原文:Understanding the CSS Modules Methodology
原文連接:http://www.sitepoint.com/understanding-css-modules-methodology/