什么是CSS模塊以及你為什么需要它們?| CSS-Tricks
#什么是CSS模塊以及你為什么需要它們?
我最近對CSS模塊很好奇。如果你還沒有聽說過它們,這篇文章就是為你而寫。我們將了解CSS模塊以及它的目的是什么。如果你也感興趣,請持續跟蹤,下一篇文章將關于怎樣使用CSS模塊。如果你想進一步提高你的CSS模塊使用技能,第三部分將關于在React環境中使用它們。
系列文章
Part 1:什么是CSS模塊以及你為什么需要它們? (你現在就在這里!) Part 2:怎樣開始用上CSS模塊 Part 3: React + CSS Modules = :heart_eyes:
什么是CSS模塊?
根據這篇 文章 ,CSS模塊是:
CSS files in which all class names and animation names are scoped locally by default. CSS文件中的所有類名(class names) 和動畫名(animation names) 的作用域都默認為當前作用域。
所以CSS模塊不是瀏覽器中的 官方標準(official spec) 或者 實踐(implementation) 而是一個(在 Webpack 或者 Browserify 的幫助下)改變類名和選擇器的作用域到當前文件(類似于命名空間)的構建過程。
這看起來像什么以及為什么這樣呢?我們將馬上看到它。首先,記住通常情況下HTML和CSS是怎么工作的。一個類名應用到HTML中:
<h1 class="title">An example heading</h1>
在CSS中定義這個類:
.title { background-color: red; }
一旦這個CSS被應用到這個HTML文檔中,應用這個類的 h1 的背景色將變為紅色。我們不需要處理CSS或者HTML。瀏覽器明白這些文件的格式。
CSS模塊采用了不同的方法。與寫純HTML不同,我們需要在一個JavaScript文件中,比如 index.js 寫我們的標記。下面這個例子告訴我們它將怎樣工作(稍后我們將采用一個更實際的例子):
import styles from "./styles.css";
element.innerHTML =
`<h1 class="${styles.title}">
An example heading
</h1>`;
在我們的構建過程中,編譯程序將查看我們引入的 styles.css 文件,隨后查看我們的JavaScript文件,將 .title 類通過 styles.title 應用。我們的構建過程接著將處理這些到一個新的、分離的HTML和CSS文件,用一個新的字符串替換HTML類屬性(HTML Class )和CSS選擇器類(CSS selector class)。
生成的HTML文件可能是這樣:
<h1 class="_styles__title_309571057">
An example heading
</h1>
生成的CSS文件可能是這樣:
._styles__title_309571057 {
background-color: red;
}
之前的類屬性和選擇器 .title 已經完全不存在了,取而代之的是一個全新的字符串。我們之前的CSS已經根本不提供給瀏覽器了。
正如 Hugo Giraudel said 在他關于這個主題的教程中提到的:
[the classes] are dynamically generated, unique, and mapped to the correct styles. [這些類]是動態生成的,是獨一無二的,并映射到正確的樣式。
這就是樣式作用域的含義。他們的作用域是特定的模板。如果我們有一個 buttons.css 文件,它將只被我們引入到 buttons.js 模板中,那么其他模板(比如 forms.js )將不能使用 .btn 這個類,除非我們也明確的將 buttons.js 引入到 forms.js 中。
為什么我們想要將CSS與HTML混合來完成這些?我們究竟為什么要這樣使用它?
為什么我們應該使用CSS模塊?
使用CSS模塊,它將保證所有樣式都作用于單個組件: 1.在一個地方 2.只應用于該組件而沒有別的
此外,任何組件都可以有一個真正的依賴關系,如
import buttons from "./buttons.css";
import padding from "./padding.css";
element.innerHTML = <div class="${buttons.red} ${padding.large}">
;</code></pre>
這種做法的目的是為了解決css中全局作用域 (global scope) 的問題
(This approach is designed to fix the problem of the global scope in CSS.)
你曾經有過試圖在一個缺乏時間和資源的情況下盡快寫出簡單的CSS而不用考慮它對其他造成的影響的情況嗎?
你曾經有在樣式表的底部殘留一些隨意的不好的片段并且嘗試去組織他們但是從來沒有組織嗎?
你曾經碰到過一些你并不能完全確認它的作用或者是否已經被使用的樣式嗎?
你曾經是否考慮過你可以移除一些樣式而不破壞其他?疑惑這個樣式是取決于自己還是依賴于其他?或者在其他地方重寫樣式?
這些問題可能會讓你很頭疼,延長項目的截止日期,并且憂傷的、渴望的望著窗外。
使用CSS模塊以及 默認當前作用域 的理念,這些問題都將被避免。當你寫樣式時你必須思考樣式的最終結果。
比如,如果你在HTML中使用 random-gross-class 而沒有將其應用為一個CSS模塊風格的類,這個樣式不會被應用,因為CSS選擇器將會被轉換為 ._style_random-gross-class_0038089 .
composes 關鍵字
建設我們有一個命名為 type.css 的文本樣式模塊。在這個文件中我們可能有以下內容:
.serif-font {
font-family: Georgia, serif;
}
.display {
composes: serif-font;
font-size: 30px;
line-height: 35px;
}
我們將在我們的模板中這樣聲明它們:
import type from "./type.css";
element.innerHTML =
`<h1 class="${type.display}">
This is a heading
</h1>`;
最終結果如下:
<h1 class="_type__display_0980340 _type__serif_404840">
Heading title
</h1>
通過使用 composes 關鍵字,所有樣式都被綁定在元素中,從而避免了 一些類似的解決方案的問題 ,比如Sass的 @extend
我們甚至可以在一個獨立的CSS文件中引入一個特定的類:
.element {
composes: dark-red from "./colors.css";
font-size: 30px;
line-height: 1.2;
}
不需要BEM
當我們使用CSS模塊時,我們并不需要使用 BEM 。有兩個原因:
-
簡單的解析:像 types.display 這樣的代碼對于開發者來說和BEM-y的 font-size__serif--large 一樣清晰明白。
-
當前作用域:假設我們在一個模塊中有一個類 .big 改變 font-size .在另一個模塊中我們用一個 相同的類名 .big 來增加不同數量的 padding 和 font-size 。這完全沒有問題!他們不會沖突,因為這些樣式將謹慎的作用于當前作用域。即使有一個模塊同時引入了這兩個樣式,在我們構建的過程中也專門為每一個類制定了自己的自定義名稱。換句話說, 專指性的問題在CSS模塊中消失了。
很酷吧?
這些都是使用CSS模塊的一些好處。
如果你有興趣學習更多, Glen Madden寫了大量的 關于CSS模塊的其他好處。
本系列的下一篇文章將關于怎樣用Webpack和CSS模塊啟動一個項目。我們會使用ES2015新特性并且在此過程中使用一些示范代碼來引導。
進一步閱讀
- CSS Modules: Welcome to the Future
- Hugo Giraudel’s CSS Modules tutorial on Sitepoint
- Understanding ES6 modules
- Let’s Learn ES2015
- Brief overview of ES6 Module Syntax
來自:http://www.zcfy.cc/article/what-are-css-modules-and-why-do-we-need-them-css-tricks-970.html