摘要:比如以為例,一個(gè)組件,包括一個(gè)文件一個(gè)文件圖片組件在中便可如下加載使用導(dǎo)出為對(duì)象的模塊化其實(shí),還有另外一種思路,就是將內(nèi)置中,成為的一部分。
CSS 模塊化
CSS(Cascading Style Sheets),從誕生之初就決定了它無(wú)法編程,甚至連解釋性語(yǔ)言都算不上,只能作為一種簡(jiǎn)單的層疊樣式表,對(duì) HTML 元素進(jìn)行格式化。
但隨著前端的發(fā)展,前端項(xiàng)目已經(jīng)變得越來(lái)越龐大和復(fù)雜,社區(qū)也一直在探索如何以一種有效的方式去管理前端的代碼(js/css/html)和資源(images, fonts, ...)。
在這個(gè)過(guò)程中,社區(qū)探索出了 js 的模塊化(amd, commonjs, es6),現(xiàn)在用 js 開(kāi)發(fā)大工程已經(jīng)游刃有余,而 css 的模塊化卻還沒(méi)有特別的深入人心。
1. 分組式模塊化這是最早對(duì) css 模塊化的實(shí)現(xiàn),也是最主要的一種方式,包括現(xiàn)在很多組件和開(kāi)發(fā)者都是用這種方式開(kāi)發(fā)的。
分組式模塊化就是用命名的方式,以不同的前綴代表不同的含義,實(shí)現(xiàn)樣式分組,文件分塊,達(dá)到模塊化的目的。
比如:
# 目錄結(jié)構(gòu) |-- one/page/css/ 某個(gè)頁(yè)面的 css 目錄 |-- common.css 通用的 css |-- page1/ 單頁(yè)面1 |-- section1.css 區(qū)域1 css |-- section2.css 區(qū)域2 css |-- page2/ 單頁(yè)面2 |-- ... # common.css 文件 .c-el-1 { ... } .c-el-2 { ... } ... # page1/section1.css 文件 .page1-section1 { ... } .page1-section1 .el-1 { ... } .page1-section1 .el-2 { ... } ... # page1/section2.css 文件 .page1-section2 { ... } .page1-section2 .el-1 { ... } .page1-section2 .el-2 { ... } ...
這種方式并不是真正意義上的模塊化,因?yàn)闊o(wú)法避免全局沖突的問(wèn)題,但原生 css 并不具備編程的能力,所以這個(gè)問(wèn)題是無(wú)法避免的。盡管分組式不算真正意義上的模塊化,但是這種方式?jīng)]有脫離 css 原生的機(jī)制,所以尤其是第三方組件在導(dǎo)出 css 文件時(shí),很多都使用的是這種方式。
比如,ant-design 導(dǎo)出的 css 中使用 ant- 前綴標(biāo)識(shí),mui 導(dǎo)出的 css 中使用 mui- 前綴標(biāo)識(shí)等等。
1.1 最佳實(shí)踐css 命名分組實(shí)踐的時(shí)間很長(zhǎng),從 css 誕生之初就有了,所以社區(qū)已經(jīng)發(fā)展很成熟了,比如網(wǎng)易的 css 規(guī)范框架 NEC,H-ui。
一個(gè) css 文件不宜過(guò)大,可以使用 @import 進(jìn)行文件分塊;
樣式渲染盡量不要使用 #id [attr],應(yīng)盡量使用 .class;
使用 js 庫(kù)操作 dom 時(shí),盡量不要用 .class,應(yīng)盡量用 #id data-set,如 $("#main"), $("[data-tab="1"]")。
因?yàn)?css 不是編程語(yǔ)言,所以不能聲明變量、函數(shù),不能做判斷、循環(huán)和計(jì)算,也不能嵌套,所以這就使得寫(xiě)樣式是一個(gè)效率底下且又枯燥的活兒。
為了解決這個(gè)問(wèn)題,社區(qū)在探索中主要衍生出了兩種拓展語(yǔ)言 less 與 sass,它們兼容 css,并且拓展了編程的功能,主要是帶來(lái)了以下的特性:
可以聲明變量、函數(shù),可以進(jìn)行一些簡(jiǎn)單的計(jì)算、判斷、循環(huán);
可以嵌套選擇器,這樣節(jié)省了書(shū)寫(xiě)的內(nèi)容,也更具閱讀性;
.page1-section1 { ... .el-1 { ... .el-1-1 { ... } } .el-2 { ... } }
@import 避免重復(fù)導(dǎo)入問(wèn)題,因此可以放心大膽的導(dǎo)入其他文件。
從模塊化的角度來(lái)講,less 與 sass 只是擴(kuò)充了 css 的功能,但并沒(méi)有在語(yǔ)言的層面做模塊化,因?yàn)槿置麤_突的問(wèn)題依然還在。
2. 模塊化(導(dǎo)出為 js 對(duì)象)想要讓 css 具備真正意義上的模塊化功能,暫時(shí)還不能從語(yǔ)言的層面來(lái)考慮,所以只能從工具的角度來(lái)實(shí)現(xiàn)。
目前比較好的方式是使用 js 來(lái)加載 css 文件,并將 css 的內(nèi)容導(dǎo)出為一個(gè)對(duì)象,使用 js 來(lái)渲染整個(gè) dom 樹(shù)和匹配相應(yīng)的樣式到對(duì)應(yīng)的元素上,在這個(gè)過(guò)程中,我們便有機(jī)會(huì)對(duì) css 做額外的處理,來(lái)達(dá)到模塊化的目的。
比如:
源文件
# style.css 文件 .className { color: green; } # js 文件 import styles from "./style.css"; element.innerHTML = "Hello!";
實(shí)際效果
# style.css 文件 ._23_aKvs-b8bW2Vg3fwHozO { color: green; } # DOMHello!
在這個(gè)轉(zhuǎn)換過(guò)程中,根據(jù)文件的位置、內(nèi)容生成一個(gè)全局唯一的 base64 字符串,替換原來(lái)的名稱(chēng),避免了全局命名沖突的問(wèn)題,這樣便達(dá)到了模塊化的目的。所以,開(kāi)發(fā)的過(guò)程中便無(wú)全局樣式?jīng)_突的問(wèn)題。
# common.css 文件 .container { ... } .el1 { ... } .el2 { ... } ... # page1/section1.css 文件 .container { ... } .title { ... } .content { ... } ... # page2/section1.css 文件 .container { ... } .title { ... } .content { ... } ...
對(duì) css 模塊化的定義參見(jiàn) css-modules,其中對(duì) css 書(shū)寫(xiě)需求主要是:
應(yīng)當(dāng)用 .class,而非#id [attr](因?yàn)橹挥?.class 才能導(dǎo)出為對(duì)象的屬性);
推薦用 .className 書(shū)寫(xiě),而非 .class-name(前者可以通過(guò) styles.className 訪(fǎng)問(wèn),后者需要通過(guò) styles["class-name"] 才能訪(fǎng)問(wèn))。
更多功能可以查看 css-modules。
當(dāng)然這個(gè)功能需要構(gòu)建工具的支持,如果你是使用 webpack 構(gòu)建工程的話(huà),可以使用 css-loader,并設(shè)置 options.modules 為 true, 便可使用模塊化的功能了。
3. 模塊化(內(nèi)置 js,綁定組件)隨著前端組件化的發(fā)展,組件化框架的更新,如 react、vue,慢慢的發(fā)展為把整個(gè)組件的資源進(jìn)行封裝,并只對(duì)外暴露一個(gè)對(duì)象,而調(diào)用者無(wú)需關(guān)心組件的內(nèi)部實(shí)現(xiàn)和資源,直接調(diào)用這個(gè)對(duì)象就夠了。
比如(以 react 為例),一個(gè) Welcome 組件,包括一個(gè) js 文件、一個(gè) css 文件、圖片:
# Welcome 組件 |-- welcome.js |-- welcome.css |-- images/
在 welcome.js 中便可如下加載(使用“導(dǎo)出為 js 對(duì)象”的 css 模塊化):
import styles from "./welcome.css"; import image1 from "./images/1.jpg";
其實(shí),還有另外一種思路,就是將 css 內(nèi)置 js 中,成為 js 的一部分。
這樣做的目的,一是 css 的模塊化,二是直接綁定到組件上。
比如,material-ui、styled-jsx、jss、vue style scoped 便是使用的這種方式。
這種方式的實(shí)現(xiàn)有很多種,這里主要介紹一下 styled-jsx。
3.1 styled-jsxstyled-jsx 的原理是根據(jù)當(dāng)前文件的位置、內(nèi)容生成一個(gè)全局唯一的標(biāo)識(shí),然后把這個(gè)標(biāo)識(shí)追加到組件每一個(gè)元素上,每一個(gè)樣式選擇器上,達(dá)到模塊化的目的。
可以參考官方文檔,查看詳細(xì)的用法,我在這里給個(gè)例子:
3.1.1 安裝工具(babel 轉(zhuǎn)碼所需)npm install --save styled-jsx3.1.2 配置 babel plugins(如 .babelrc)
{ "plugins": [ "styled-jsx/babel" ] }3.1.3 添加源文件代碼
hello.js
export default () => (3.1.4 轉(zhuǎn)碼)Hello! Hello!
Hi!
babel path/to/hello.js -d target/dir
轉(zhuǎn)碼后的文件
import _JSXStyle from "styled-jsx/style"; export default () => (3.1.5 運(yùn)行);Hello! Hello!
Hi!<_JSXStyle styleId={"234963469"} css={".container.jsx-234963469{color:blue;}p.jsx-234963469:first-child{color:red;}.hello.jsx-234963469{color:yellow;}#hi.jsx-234963469{color:green;}"} />
實(shí)際渲染效果
4. 后續(xù)Hello! Hello!
Hi!
更多博客,查看 https://github.com/senntyou/blogs
作者:深予之 (@senntyou)
版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名(創(chuàng)意共享3.0許可證)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/116769.html
摘要:一般建議文件最大不超過(guò)。按需加載可以減小首屏加載文件的體積,達(dá)到提高響應(yīng)速度的目的。如果你的項(xiàng)目不需要處理靜態(tài)資源如圖片,也不需要按需加載,并追求前端高性能的話(huà),可以嘗試。 如何提升前端性能和響應(yīng)速度 下面大多是從前端工程化的角度給出的優(yōu)化建議,如果需要了解語(yǔ)法上的優(yōu)化,可以參考: 如何提高頁(yè)面加載速度 編寫(xiě)高效的JavaScript Web前端性能優(yōu)化進(jìn)階 - 完結(jié)篇 1. 原生...
摘要:一般建議文件最大不超過(guò)。按需加載可以減小首屏加載文件的體積,達(dá)到提高響應(yīng)速度的目的。如果你的項(xiàng)目不需要處理靜態(tài)資源如圖片,也不需要按需加載,并追求前端高性能的話(huà),可以嘗試。 如何提升前端性能和響應(yīng)速度 下面大多是從前端工程化的角度給出的優(yōu)化建議,如果需要了解語(yǔ)法上的優(yōu)化,可以參考: 如何提高頁(yè)面加載速度 編寫(xiě)高效的JavaScript Web前端性能優(yōu)化進(jìn)階 - 完結(jié)篇 1. 原生...
摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒(méi)想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...
摘要:比如以為例,一個(gè)組件,包括一個(gè)文件一個(gè)文件圖片組件在中便可如下加載使用導(dǎo)出為對(duì)象的模塊化其實(shí),還有另外一種思路,就是將內(nèi)置中,成為的一部分。 CSS 模塊化 CSS(Cascading Style Sheets),從誕生之初就決定了它無(wú)法編程,甚至連解釋性語(yǔ)言都算不上,只能作為一種簡(jiǎn)單的層疊樣式表,對(duì) HTML 元素進(jìn)行格式化。 但隨著前端的發(fā)展,前端項(xiàng)目已經(jīng)變得越來(lái)越龐大和復(fù)雜,社區(qū)...
摘要:進(jìn)階的知識(shí)的話(huà)就是響應(yīng)式這一塊了,一套代碼能適配手機(jī)是初級(jí)前端工程師的進(jìn)階,在北京工資一般在左右。進(jìn)階的知識(shí)應(yīng)該是這一塊了,當(dāng)然并不難,了解怎么與后臺(tái)交互是學(xué)習(xí)的關(guān)鍵點(diǎn),在北京的工資一般在左右。 web前端?如果你是一名web前端工程師,那么你將感到幸運(yùn),從之前的默默無(wú)聞,到后來(lái)的給后臺(tái)工程師打下手,再到巔峰一時(shí)。web前端可謂是當(dāng)下最火的職位之一。 showImg(https://s...
閱讀 1984·2021-11-23 10:03
閱讀 4185·2021-11-22 09:34
閱讀 2492·2021-10-08 10:05
閱讀 2256·2019-08-30 15:53
閱讀 1694·2019-08-30 13:56
閱讀 1164·2019-08-29 16:52
閱讀 1114·2019-08-26 13:31
閱讀 3354·2019-08-26 11:45