摘要:示例庫通過記錄來查看定制類名默認的哈希算法是,從前面我們可以發(fā)現(xiàn)被編譯成了這樣的字符串。與上面不加等價顯式的局部作用域語法通過示例庫的記錄來查看下的樣式復用對于樣式復用,提供了組合的方式來處理。
前端發(fā)展越來越快,這應該是每個前端開發(fā)者的切身感受,但是CSS 是前端領域中進化最慢的一塊。ES678快速普及前端工程發(fā)愈發(fā)成熟,CSS 被被遠遠甩在了后面,JS語言模塊已經(jīng)標準化,CSS還是在不斷探索,同時這也是一個急需解決的問題。
要是你以前還從未聽說過CSS Modules,那么這篇就是專門寫給你的。如果你了解過它,你就沒必要再看了,因為他真的很簡單(很強大)。
CSS的痛點我們都知道,CSS入門簡單,深入就比較難,樣式簡單維護難。CSS痛點也很多
1、CSS 的規(guī)則是全局的,任何一個組件的樣式規(guī)則,都對整個頁面有效。相信寫css的人都會遇到樣式?jīng)_突(污染)的問題。
2、為了解決全局污染的問題,那就把class命名寫長一點吧、加一層父級選擇器、降低沖突的幾率,那么CSS命名混亂了
3、組件依賴管理不徹底,組件應該相互獨立,引入一個組件時,應該只引入它所需要的 CSS 樣式。
4、代碼難以復用,出現(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 來管理樣式模塊使用JS編譯原生的CSS文件,使其具備模塊化的能力,代表是 CSS Modules。
但是這些模塊化方案都是各有優(yōu)缺點,如命名約定:命名復雜、CSS in JS:缺乏擴展、 CSS Modules當然也有一些缺點(你得先學會它再去談優(yōu)劣)。在眾多解決方案中,沒有絕對的優(yōu)劣。還是要結合自己的場景來決定。
使用 CSS ModulesCSS Modules不是將CSS改造的具有編程能力,而是加入了局部作用域、依賴管理,這恰恰解決了最大的痛點。可以有效避免全局污染和樣式?jīng)_突,能最大化地結合現(xiàn)有 CSS 生態(tài)和 JS 模塊化能力。
啟用 CSS ModulesCSS Modules 很容易學。webpack 自帶的?css-loader?組件,自帶了 CSS Modules,通過簡單的配置即可使用。
// 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)在我們來寫個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 對 CSS 中的 class 名都做了處理,使用對象來保存原 class 和混淆后 class 的對應關系。CSS Modules自動生成的class類名基本就是唯一的,大大降低了項目中樣式覆蓋沖突的幾率。
GitHub 示例庫 https://github.com/liuxing/css-modules-demo 通過commit 記錄來查看
定制class類名css-loader默認的哈希算法是[hash:base64],從前面我們可以發(fā)現(xiàn).primary 被編譯成了 yTXmm0isaXExoYiZUvKxH 這樣的字符串。這名字也沒風格了別擔心,css-loader 為我們提供了localIdentName 參數(shù)指定生成的名字格式。localIdentName的默認值是[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的同學可能發(fā)現(xiàn)了上面的命名和BEM有些神似, 雖然它的命名有點奇特,但是 BEM 被非常多的大型項目和團隊采用,這是一種很好的實踐。當然了隨便怎么寫都可以結合自己的場景來決定,在CSS module中不再需要遵守BEM規(guī)范。
作用域通過前面的例子可以感受到CSS module處理CSS的方式。現(xiàn)在我們從頭來說作用域。
默認局部作用CSS很多問題都是因為全局作用域引起的,怎么樣才能產(chǎn)生局部作用域?通過前面CSS module的例子我們發(fā)現(xiàn)它思路很簡單就是生成唯一的class類名。CSS module將class轉(zhuǎn)換成對應的全局唯一hash值來形成局部作用域。使用了 CSS Modules 后,就相當于給每個 class 名外加了一個?:local 這是默認的,也可以顯式使用
當然,如果你想切換到全局模式,CSS Modules 允許使用:global(.className)的語法,聲明一個全局規(guī)則。凡是這樣聲明的class,都不會被編譯成哈希字符串。
/* Button.css */ :global(.btn) { color: #fff; border: none; border-radius: 5px; } .primary { background-color: #1aad19; } /* 與上面不加`:local`等價 顯式的局部作用域語法 */ :local(.warn) { background-color: #e64340 }
通過 GitHub 示例庫 https://github.com/liuxing/css-modules-demo 的commit 記錄來查看
CSS Modules下的樣式復用對于樣式復用,CSS Modules 提供了 composes?組合 的方式來處理。一個選擇器可以繼承另一個選擇器的規(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?會變成兩個 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; } ···
這是個很強大方便的功能,CSS Modules團隊成員認為composes是CSS Modules里最強大的功能:
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.一些建議
為了追求簡單可控,作者建議遵循如下原則:
不使用選擇器,只使用 class 名來定義樣式
不層疊多個 class,只使用一個 class 把所有樣式定義好
所有樣式通過 composes 組合來實現(xiàn)復用
不嵌套
但是建議只是建議,CSS Modules 并不強制你一定要這么做。怎么舒服怎么來
CSS Modules 很好的解決了 CSS 目前面臨的一些痛點以及模塊化難題,同時也支持與 Sass/Less/PostCSS 等搭配使用。
無論是通過遵循的命名標準化的規(guī)范,還是使用本文介紹的CSS Modules,目的都是一樣:可維護的css代碼。具體使用不是有還是要結合自己的場景來決定。適合的才是最好的
大家可以關注我的公眾號,一起玩耍。有技術干貨也有扯淡亂談,關注回復[888]領取福利
左手代碼右手磚,拋磚引玉
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/113208.html
摘要:介紹背景最近和部門老大,一起在研究團隊前端新手村的建設,目的在于幫助新人快速了解和融入公司團隊,幫助零基礎新人學習和入門前端開發(fā)并且達到公司業(yè)務開發(fā)水平。 showImg(https://segmentfault.com/img/remote/1460000020063710?w=1300&h=646); 介紹 1. 背景 最近和部門老大,一起在研究團隊【EFT - 前端新手村】的建設...
摘要:我們可以根據(jù)模塊類型擴展名來自動綁定需要的。當需要加載的文件匹配的正則時,就會調(diào)用后面的對文件進行處理,這正是強大的原因。這篇就這樣吧,感覺進度有點慢從入門到放棄四從入門到放棄一從入門到放棄三源代碼 Foreword 上一篇簡單介紹了webpack的打包功能,應該說是比較無意義的打包,對于開發(fā)人員來說,這種效率是非常低的。所以我們來點升華。 First Step 我們給第一篇例子中加個...
摘要:我們可以根據(jù)模塊類型擴展名來自動綁定需要的。當需要加載的文件匹配的正則時,就會調(diào)用后面的對文件進行處理,這正是強大的原因。這篇就這樣吧,感覺進度有點慢從入門到放棄四從入門到放棄一從入門到放棄三源代碼 Foreword 上一篇簡單介紹了webpack的打包功能,應該說是比較無意義的打包,對于開發(fā)人員來說,這種效率是非常低的。所以我們來點升華。 First Step 我們給第一篇例子中加個...
摘要:這就需要把文件單獨拎出來,那需要一個插件來配合才能完成版本需要以上,低版本請使用使用步驟安裝在里引入模塊寫入陳學輝文件目錄會放入里寫入代替執(zhí)行命令后可以看到目錄里已經(jīng)多了一個文件夾,這個文件夾里放了一個文件。 概念 在webpack中任何一個東西都稱為模塊,js就不用說了。一個css文件,一張圖片、一個less文件都是一個模塊,都能用導入模塊的語法(commonjs的require,E...
摘要:最后還可以跟我們的進行結合管理代碼什么是說明白點就是模塊打包機,可以很好的管理我們的模塊,可以對瀏覽器進行更好的兼容。安裝首選我們要安裝,中已經(jīng)給我們下載了我們通過進行安裝管理。 webpack入門及結合react進行開發(fā) 重要提示(2017年7月26號更新) 本文介紹的是最新版的3.4.1,并且其中又跟React結合的例子!showImg(https://segmentfault.c...
閱讀 3640·2023-04-26 02:07
閱讀 3150·2021-09-22 15:55
閱讀 2533·2021-07-26 23:38
閱讀 3119·2019-08-29 15:16
閱讀 2008·2019-08-29 11:16
閱讀 1745·2019-08-29 11:00
閱讀 3582·2019-08-26 18:36
閱讀 3164·2019-08-26 13:32