我最近對(duì)CSS模塊很感興趣。如果你還沒(méi)有聽(tīng)說(shuō)過(guò)洞翩,這篇文章是給你的稽犁。我們將關(guān)注該項(xiàng)目及其目標(biāo)和目的。如果你感興趣菱农,請(qǐng)繼續(xù)關(guān)注缭付,因?yàn)橄乱黄恼聦⒔榻B如何開(kāi)始使用這個(gè)想法。如果您希望實(shí)現(xiàn)或提高使用率循未,第3部分將介紹在React環(huán)境中使用它們陷猫。
文章系列:
1. 什么是CSS模塊秫舌,我們?yōu)槭裁葱枰鼈儯浚阍谶@里P迕省)
2. CSS模塊入門(mén)
3. React+CSS模塊=??
什么是CSS模塊足陨?
根據(jù)回購(gòu)協(xié)議,CSS模塊包括:
默認(rèn)情況下娇未,所有類(lèi)名和動(dòng)畫(huà)名稱(chēng)的作用域都在本地的CSS文件墨缘。
因此,CSS模塊不是官方規(guī)范或?yàn)g覽器中的實(shí)現(xiàn)零抬,而是構(gòu)建步驟中的一個(gè)過(guò)程(在Webpack或Browserify的幫助下)镊讼,該過(guò)程將更改類(lèi)名和選擇器的作用域(即有點(diǎn)像命名空間)。
這看起來(lái)像什么平夜?為什么蝶棋?我們將在稍后介紹。首先忽妒,請(qǐng)記住HTML和CSS通常是如何工作的玩裙。類(lèi)應(yīng)用于HTML:
<h1 class="title">An example heading</h1>
該類(lèi)采用CSS樣式:
.title {
background-color: red;
}
只要CSS應(yīng)用于HTML文檔,<h1>的背景將是紅色的段直。我們不需要處理CSS或HTML吃溅。瀏覽器可以理解這兩種文件格式。
CSS模塊采用不同的方法鸯檬。我們需要在JavaScript文件中編寫(xiě)所有標(biāo)記决侈,而不是編寫(xiě)純HTML,比如index.js京闰。下面是一個(gè)如何工作的示例(稍后我們將查看一個(gè)更現(xiàn)實(shí)的示例):
import styles from "./styles.css";
element.innerHTML =
`<h1 class="${styles.title}">
An example heading
</h1>`;
在我們的構(gòu)建步驟中颜及,編譯器將搜索這些樣式。css文件蹂楣,然后查看我們編寫(xiě)的JavaScript俏站,并通過(guò)styles.title訪問(wèn).title類(lèi)。然后痊土,我們的構(gòu)建步驟將把這兩個(gè)東西處理成新的肄扎、單獨(dú)的HTML和CSS文件,用一個(gè)新的字符串替換HTML類(lèi)和CSS選擇器類(lèi)赁酝。
我們生成的HTML可能如下所示:
<h1 class="_styles__title_309571057">
An example heading
</h1>
我們生成的CSS可能如下所示:
._styles__title_309571057 {
background-color: red;
}
class屬性和selector.title完全消失犯祠,取而代之的是這個(gè)全新的字符串;我們的原始CSS根本沒(méi)有提供給瀏覽器酌呆。
正如Kitty Giraudel在關(guān)于該主題的教程中所說(shuō):
[類(lèi)]是動(dòng)態(tài)生成的衡载、唯一的,并映射到正確的樣式隙袁。
這就是樣式作用域的含義痰娱。它們的作用域是特定的模板弃榨。如果我們有按鈕。css文件梨睁,我們只能將其導(dǎo)入到按鈕中鲸睛。js模板和其中的.btn類(lèi)對(duì)于其他模板(例如forms.js)是不可訪問(wèn)的,除非我們也將其專(zhuān)門(mén)導(dǎo)入到那里坡贺。
為什么我們要用CSS和HTML來(lái)做這件事官辈?我們到底為什么要這樣做?
為什么要使用CSS模塊遍坟?
使用CSS模塊拳亿,可以保證單個(gè)組件的所有樣式:
住在一個(gè)地方
僅適用于該組件,不適用于其他組件
此外愿伴,任何組件都可以具有真正的依賴(lài)關(guān)系风瘦,例如:
import buttons from "./buttons.css";
import padding from "./padding.css";
element.innerHTML = `<div class="${buttons.red} ${padding.large}">`;
此方法旨在解決CSS中的全局范圍問(wèn)題。
- 你是否曾因?yàn)槿狈r(shí)間或資源而試圖盡可能快地編寫(xiě)CSS公般,而不考慮你可能會(huì)影響到什么?
- 您是否曾在樣式表的底部隨意添加一些垃圾胡桨,打算組織它官帘,但從未這樣做過(guò)?
- 你有沒(méi)有遇到過(guò)你不完全確定它們做了什么或者它們是否被使用的風(fēng)格昧谊?
- 你有沒(méi)有想過(guò)刽虹,如果你能在不破壞一些東西的情況下擺脫一些風(fēng)格?想知道這些風(fēng)格是獨(dú)立的還是依賴(lài)于其他東西呢诬?或者在其他地方重寫(xiě)樣式涌哲?
這些問(wèn)題可能會(huì)導(dǎo)致嚴(yán)重的頭痛、項(xiàng)目期限過(guò)長(zhǎng)以及窗外的悲傷和渴望尚镰。
使用CSS模塊和默認(rèn)的本地范圍概念阀圾,可以避免這個(gè)問(wèn)題。你總是被迫在寫(xiě)作風(fēng)格時(shí)考慮后果狗唉。
例如初烘,如果在HTML中使用隨機(jī)的gross類(lèi),而不將其作為CSS模塊樣式類(lèi)應(yīng)用分俯,則不會(huì)應(yīng)用該樣式肾筐,因?yàn)镃SS選擇器將轉(zhuǎn)換為.style_random-gross-class_0038089。
compose關(guān)鍵字
假設(shè)我們有一個(gè)名為type的模塊缸剪。css用于我們的文本樣式吗铐。在該文件中,我們可能有以下內(nèi)容:
.serif-font {
font-family: Georgia, serif;
}
.display {
composes: serif-font;
font-size: 30px;
line-height: 35px;
}
我們將在模板中聲明其中一個(gè)類(lèi)杏节,如下所示:
import type from "./type.css";
element.innerHTML =
`<h1 class="${type.display}">
This is a heading
</h1>`;
這將導(dǎo)致如下標(biāo)記:
<h1 class="_type__display_0980340 _type__serif_404840">
Heading title
</h1>
這兩個(gè)類(lèi)都通過(guò)使用composite關(guān)鍵字綁定到元素唬渗,從而避免了類(lèi)似解決方案的一些問(wèn)題典阵,如Sass的@extend。
我們甚至可以從一個(gè)單獨(dú)的CSS文件中的特定類(lèi)進(jìn)行編寫(xiě):
.element {
composes: dark-red from "./colors.css";
font-size: 30px;
line-height: 1.2;
}
不需要BEM
我們?cè)谥谱鰿SS模塊時(shí)不需要使用BEM谣妻。這有兩個(gè)原因:
1.易于解析–類(lèi)似代碼的類(lèi)型萄喳。對(duì)于開(kāi)發(fā)人員來(lái)說(shuō),顯示屏和BEM-y.font-size__serif一樣清晰——大蹋半。當(dāng)BEM選擇器變長(zhǎng)時(shí)他巨,可能更容易在心理上解析。
- 本地范圍–假設(shè)我們?cè)谝粋€(gè)模塊中有一個(gè)類(lèi)减江,比如.big染突,它會(huì)改變字體大小。在另一個(gè)例子中辈灼,我們使用了完全相同的class.big份企,它以不同的數(shù)量增加了填充和字體大小。這根本不重要巡莹!它們不會(huì)發(fā)生沖突司志,因?yàn)闃邮降姆秶浅C鞔_。即使一個(gè)模塊同時(shí)導(dǎo)入兩個(gè)樣式表降宅,它也有一個(gè)我們的構(gòu)建過(guò)程專(zhuān)門(mén)為該類(lèi)創(chuàng)建的自定義名稱(chēng)骂远。換句話說(shuō),CSS模塊的特殊性問(wèn)題消失了腰根。
酷吧激才?
這些只是編寫(xiě)CSS模塊的一些好處。