CSS 規則的範圍是全域的。放到 JavaScript 環境裡說,我們寫的每一條 CSS 規則,都相當於定義一個全域變數。全域變數多了,命名衝突、副作用、代碼不可預測等問題就開始浮現。我們無妨把 CSS 想象成一頭野馬,我們所有的 CSS 命名規範上的嘗試,無論是 SUITCSS 還是 BEM、SMACSS 或是其它,都是打算給 CSS 套上韁繩,但我們只是往正確的方向走了一小步。命名規範只是一種約定,如果開發人員有意或無意地忽視,哪怕只是代碼中的一小部分,也會給以後埋下問題。
所以我們可以看到,在 JavaScript 模組化非常成熟、各類工具齊全的今天,前端界開始往 CSS 模組化方向努力。
我最早瞭解到的這方面努力是 ember-component-css,比如 app/my-component/styles.css 檔案內容如下:
& {
padding: 2px;
}
.urgent {
color: red;
}
構建後的 CSS 如下:
.my-component-a34fba {
padding: 2px;
}
.my-component-a34fba .urgent {
color: red;
}
構建後的 CSS 範圍不再是全域,而是限定在這個組件中,我們把 CSS 關進模組化的籠子。我們不用擔心它的作用會滲透到其他代碼,我們現在對我們的代碼作用範圍非常有信心 – 它現在更像是狙擊槍,而不是手榴彈。
接下來,我在用 JSPM 時也看到模組化 CSS 的努力。
然後是 webpack 的 CSS Module mode,開發這塊功能的這位甚至宣布了全域 CSS 的終結。
從上面的簡單介紹中可以看到,CSS 的模組化依賴於特定工具,比如 ember-cli、webpack、jspm,如果我們不用這類工具的話,就基本無法對 CSS 做模組化,這樣移植性似乎差了點,而且因為沒有標準規範,所以它們的實施也不盡相同。可是這年頭,不用這類工具輔助的代碼,恐怕代碼在可維護性、可擴充方面都會很糟糕吧。