摘要:示例庫(kù)通過(guò)記錄來(lái)查看定制類名默認(rèn)的哈希算法是,從前面我們可以發(fā)現(xiàn)被編譯成了這樣的字符串。與上面不加等價(jià)顯式的局部作用域語(yǔ)法通過(guò)示例庫(kù)的記錄來(lái)查看下的樣式復(fù)用對(duì)于樣式復(fù)用,提供了組合的方式來(lái)處理。
前端發(fā)展越來(lái)越快,這應(yīng)該是每個(gè)前端開發(fā)者的切身感受,但是CSS 是前端領(lǐng)域中進(jìn)化最慢的一塊。ES678快速普及前端工程發(fā)愈發(fā)成熟,CSS 被被遠(yuǎn)遠(yuǎn)甩在了后面,JS語(yǔ)言模塊已經(jīng)標(biāo)準(zhǔn)化,CSS還是在不斷探索,同時(shí)這也是一個(gè)急需解決的問(wèn)題。
要是你以前還從未聽說(shuō)過(guò)CSS Modules,那么這篇就是專門寫給你的。如果你了解過(guò)它,你就沒必要再看了,因?yàn)樗娴暮芎?jiǎn)單(很強(qiáng)大)。
CSS的痛點(diǎn)我們都知道,CSS入門簡(jiǎn)單,深入就比較難,樣式簡(jiǎn)單維護(hù)難。CSS痛點(diǎn)也很多
1、CSS 的規(guī)則是全局的,任何一個(gè)組件的樣式規(guī)則,都對(duì)整個(gè)頁(yè)面有效。相信寫css的人都會(huì)遇到樣式?jīng)_突(污染)的問(wèn)題。
2、為了解決全局污染的問(wèn)題,那就把class命名寫長(zhǎng)一點(diǎn)吧、加一層父級(jí)選擇器、降低沖突的幾率,那么CSS命名混亂了
3、組件依賴管理不徹底,組件應(yīng)該相互獨(dú)立,引入一個(gè)組件時(shí),應(yīng)該只引入它所需要的 CSS 樣式。
4、代碼難以復(fù)用,出現(xiàn)了sass less 之類的工具
CSS模塊化方案分類前端發(fā)展是飛速的天天有新輪子。自然CSS 模塊化的解決方案有很多,但主要有三類:
1、命名約定規(guī)范化CSS的解決方案如:BEM、OOCSS、AMCSS、SMACSS
2、CSS in JS徹底拋棄 CSS,用 JavaScript 寫 CSS 規(guī)則,styled-components?就是其中代表。
3、使用JS 來(lái)管理樣式模塊使用JS編譯原生的CSS文件,使其具備模塊化的能力,代表是 CSS Modules。
但是這些模塊化方案都是各有優(yōu)缺點(diǎn),如命名約定:命名復(fù)雜、CSS in JS:缺乏擴(kuò)展、 CSS Modules當(dāng)然也有一些缺點(diǎn)(你得先學(xué)會(huì)它再去談優(yōu)劣)。在眾多解決方案中,沒有絕對(duì)的優(yōu)劣。還是要結(jié)合自己的場(chǎng)景來(lái)決定。
使用 CSS ModulesCSS Modules不是將CSS改造的具有編程能力,而是加入了局部作用域、依賴管理,這恰恰解決了最大的痛點(diǎn)。可以有效避免全局污染和樣式?jīng)_突,能最大化地結(jié)合現(xiàn)有 CSS 生態(tài)和 JS 模塊化能力。
啟用 CSS ModulesCSS Modules 很容易學(xué)。webpack 自帶的?css-loader?組件,自帶了 CSS Modules,通過(guò)簡(jiǎn)單的配置即可使用。
// webpack.config.js const path = require("path") module.exports = { entry: __dirname + "/src/index.js", output: { filename: "bundle.js", path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /.css$/, use: [ "style-loader", { loader: "css-loader", options: { modules: true, } } ] } ] } } // 也可以使用下面這種寫法 // loader: "style-loader!css-loader?modules"
現(xiàn)在我們來(lái)寫個(gè)Button組件
/* Button.css */ .primary { background-color: #1aad19; color: #fff; border: none; border-radius: 5px; }
// Button.js import styles from "./Button.css"; console.log(styles); // -> {primary: "yTXmm0isaXExoYiZUvKxH"} const Button = document.createElement("div") Button.innerHTML = `` export default Button // index.js import Button from "./components/Button" const app = document.getElementById("root") app.appendChild(Button)
生成HTML為
CSS Modules 對(duì) CSS 中的 class 名都做了處理,使用對(duì)象來(lái)保存原 class 和混淆后 class 的對(duì)應(yīng)關(guān)系。CSS Modules自動(dòng)生成的class類名基本就是唯一的,大大降低了項(xiàng)目中樣式覆蓋沖突的幾率。
GitHub 示例庫(kù) https://github.com/liuxing/css-modules-demo 通過(guò)commit 記錄來(lái)查看
定制class類名css-loader默認(rèn)的哈希算法是[hash:base64],從前面我們可以發(fā)現(xiàn).primary 被編譯成了 yTXmm0isaXExoYiZUvKxH 這樣的字符串。這名字也沒風(fēng)格了別擔(dān)心,css-loader 為我們提供了localIdentName 參數(shù)指定生成的名字格式。localIdentName的默認(rèn)值是[hash:base64]。
... { loader: "css-loader", options: { modules: true, localIdentName: "[name]__[local]--[hash:base64:5]" } } // 或者 loader: "style-loader!css-loader?modules&localIdentName=[name]__[local]--[hash:base64:5]" ...
BEM代碼規(guī)范不再是必須的 熟悉BEM的同學(xué)可能發(fā)現(xiàn)了上面的命名和BEM有些神似, 雖然它的命名有點(diǎn)奇特,但是 BEM 被非常多的大型項(xiàng)目和團(tuán)隊(duì)采用,這是一種很好的實(shí)踐。當(dāng)然了隨便怎么寫都可以結(jié)合自己的場(chǎng)景來(lái)決定,在CSS module中不再需要遵守BEM規(guī)范。
作用域通過(guò)前面的例子可以感受到CSS module處理CSS的方式?,F(xiàn)在我們從頭來(lái)說(shuō)作用域。
默認(rèn)局部作用CSS很多問(wèn)題都是因?yàn)槿肿饔糜蛞鸬?,怎么樣才能產(chǎn)生局部作用域?通過(guò)前面CSS module的例子我們發(fā)現(xiàn)它思路很簡(jiǎn)單就是生成唯一的class類名。CSS module將class轉(zhuǎn)換成對(duì)應(yīng)的全局唯一hash值來(lái)形成局部作用域。使用了 CSS Modules 后,就相當(dāng)于給每個(gè) class 名外加了一個(gè)?:local 這是默認(rèn)的,也可以顯式使用
當(dāng)然,如果你想切換到全局模式,CSS Modules 允許使用:global(.className)的語(yǔ)法,聲明一個(gè)全局規(guī)則。凡是這樣聲明的class,都不會(huì)被編譯成哈希字符串。
/* Button.css */ :global(.btn) { color: #fff; border: none; border-radius: 5px; } .primary { background-color: #1aad19; } /* 與上面不加`:local`等價(jià) 顯式的局部作用域語(yǔ)法 */ :local(.warn) { background-color: #e64340 }
通過(guò) GitHub 示例庫(kù) https://github.com/liuxing/css-modules-demo 的commit 記錄來(lái)查看
CSS Modules下的樣式復(fù)用對(duì)于樣式復(fù)用,CSS Modules 提供了 composes?組合 的方式來(lái)處理。一個(gè)選擇器可以繼承另一個(gè)選擇器的規(guī)則
/* Button.css */ .btn { /* 所有通用的樣式 */ color: #fff; border: none; border-radius: 5px; box-sizing: border-box; } .primary { composes: btn; background-color: #1aad19; }
Button.js
import styles from "./Button.css"; console.log(styles); const Button = document.createElement("div") Button.innerHTML = `` export default Button
生成的 HTML 變?yōu)?/p>
我們發(fā)現(xiàn)在?.primary?中 composes 了?.btn,編譯后 .primary?會(huì)變成兩個(gè) class。
composes 還可以也可以繼承組合其他CSS文件里面的規(guī)則
/* author.css */ .shadow { box-shadow: 0 0 20px rgba(0, 0, 0, .2) }
Button.css
··· .primary { composes: btn; composes: shadow from "./author.css"; background-color: #1aad19; } ···
這是個(gè)很強(qiáng)大方便的功能,CSS Modules團(tuán)隊(duì)成員認(rèn)為composes是CSS Modules里最強(qiáng)大的功能:
For me, the most powerful idea in CSS Modules is composition, where you can deconstruct your visual inventory into atomic classes, and assemble them at a module level, without duplicating markup or hindering performance.一些建議
為了追求簡(jiǎn)單可控,作者建議遵循如下原則:
不使用選擇器,只使用 class 名來(lái)定義樣式
不層疊多個(gè) class,只使用一個(gè) class 把所有樣式定義好
所有樣式通過(guò) composes 組合來(lái)實(shí)現(xiàn)復(fù)用
不嵌套
但是建議只是建議,CSS Modules 并不強(qiáng)制你一定要這么做。怎么舒服怎么來(lái)
CSS Modules 很好的解決了 CSS 目前面臨的一些痛點(diǎn)以及模塊化難題,同時(shí)也支持與 Sass/Less/PostCSS 等搭配使用。
無(wú)論是通過(guò)遵循的命名標(biāo)準(zhǔn)化的規(guī)范,還是使用本文介紹的CSS Modules,目的都是一樣:可維護(hù)的css代碼。具體使用不是有還是要結(jié)合自己的場(chǎng)景來(lái)決定。適合的才是最好的
大家可以關(guān)注我的公眾號(hào),一起玩耍。有技術(shù)干貨也有扯淡亂談,關(guān)注回復(fù)[888]領(lǐng)取福利
左手代碼右手磚,拋磚引玉
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/113208.html
摘要:介紹背景最近和部門老大,一起在研究團(tuán)隊(duì)前端新手村的建設(shè),目的在于幫助新人快速了解和融入公司團(tuán)隊(duì),幫助零基礎(chǔ)新人學(xué)習(xí)和入門前端開發(fā)并且達(dá)到公司業(yè)務(wù)開發(fā)水平。 showImg(https://segmentfault.com/img/remote/1460000020063710?w=1300&h=646); 介紹 1. 背景 最近和部門老大,一起在研究團(tuán)隊(duì)【EFT - 前端新手村】的建設(shè)...
摘要:我們可以根據(jù)模塊類型擴(kuò)展名來(lái)自動(dòng)綁定需要的。當(dāng)需要加載的文件匹配的正則時(shí),就會(huì)調(diào)用后面的對(duì)文件進(jìn)行處理,這正是強(qiáng)大的原因。這篇就這樣吧,感覺進(jìn)度有點(diǎn)慢從入門到放棄四從入門到放棄一從入門到放棄三源代碼 Foreword 上一篇簡(jiǎn)單介紹了webpack的打包功能,應(yīng)該說(shuō)是比較無(wú)意義的打包,對(duì)于開發(fā)人員來(lái)說(shuō),這種效率是非常低的。所以我們來(lái)點(diǎn)升華。 First Step 我們給第一篇例子中加個(gè)...
摘要:我們可以根據(jù)模塊類型擴(kuò)展名來(lái)自動(dòng)綁定需要的。當(dāng)需要加載的文件匹配的正則時(shí),就會(huì)調(diào)用后面的對(duì)文件進(jìn)行處理,這正是強(qiáng)大的原因。這篇就這樣吧,感覺進(jìn)度有點(diǎn)慢從入門到放棄四從入門到放棄一從入門到放棄三源代碼 Foreword 上一篇簡(jiǎn)單介紹了webpack的打包功能,應(yīng)該說(shuō)是比較無(wú)意義的打包,對(duì)于開發(fā)人員來(lái)說(shuō),這種效率是非常低的。所以我們來(lái)點(diǎn)升華。 First Step 我們給第一篇例子中加個(gè)...
摘要:這就需要把文件單獨(dú)拎出來(lái),那需要一個(gè)插件來(lái)配合才能完成版本需要以上,低版本請(qǐng)使用使用步驟安裝在里引入模塊寫入陳學(xué)輝文件目錄會(huì)放入里寫入代替執(zhí)行命令后可以看到目錄里已經(jīng)多了一個(gè)文件夾,這個(gè)文件夾里放了一個(gè)文件。 概念 在webpack中任何一個(gè)東西都稱為模塊,js就不用說(shuō)了。一個(gè)css文件,一張圖片、一個(gè)less文件都是一個(gè)模塊,都能用導(dǎo)入模塊的語(yǔ)法(commonjs的require,E...
摘要:最后還可以跟我們的進(jìn)行結(jié)合管理代碼什么是說(shuō)明白點(diǎn)就是模塊打包機(jī),可以很好的管理我們的模塊,可以對(duì)瀏覽器進(jìn)行更好的兼容。安裝首選我們要安裝,中已經(jīng)給我們下載了我們通過(guò)進(jìn)行安裝管理。 webpack入門及結(jié)合react進(jìn)行開發(fā) 重要提示(2017年7月26號(hào)更新) 本文介紹的是最新版的3.4.1,并且其中又跟React結(jié)合的例子!showImg(https://segmentfault.c...
閱讀 3844·2023-04-26 02:07
閱讀 3290·2021-09-22 15:55
閱讀 2609·2021-07-26 23:38
閱讀 3209·2019-08-29 15:16
閱讀 2068·2019-08-29 11:16
閱讀 1828·2019-08-29 11:00
閱讀 3720·2019-08-26 18:36
閱讀 3230·2019-08-26 13:32