這幾個(gè)CSS概念,你了解嗎?
本文轉(zhuǎn)載自微信公眾號「前端那些趣事」,作者樹醬君。轉(zhuǎn)載本文請聯(lián)系前端那些趣事公眾號。
聊起css,印象最深刻的就是剛畢業(yè)那會剛開始從事前端開發(fā)崗位工作的時(shí)候,身為一名 cut picture boy (切圖仔),在頁面布局及還原設(shè)計(jì)圖中廣泛使用css來開發(fā)頁面,我記得剛開始接觸最多的就是Bootstrap(用于開發(fā)響應(yīng)式布局、移動(dòng)設(shè)備優(yōu)先的 WEB)。然而隨著前端突飛猛進(jìn)的編進(jìn),諸如element,ant design等優(yōu)秀的ui庫出現(xiàn),在對比中感到審美疲勞。言歸正傳,css近年來了也催生了蠻多新的解決方案,比如 CSS Modules、styled-components(css in js )、Functional CSS、CSS 原子類、CSS沙盒等等
1. CSS Module
CSS Module 顧名思義就是 CSS 模塊化,為什么需要模塊化?我們知道隨著基于vue、react開發(fā)SPA的web應(yīng)用,本質(zhì)上是由多組件搭建而成,就好比用積木來搭房子,如果這個(gè)時(shí)候兩個(gè)組件的樣式類名重復(fù)了,那豈不是就沖突了?為了解決沖突就需要進(jìn)行模塊化區(qū)分,沒有了命名沖突,更好的讓組件間沙箱化,而CSS Module就是css模塊化的實(shí)現(xiàn)方式之一
CSS Module 在打包的時(shí)候會將類名轉(zhuǎn)換成帶有hash值的新類名,根據(jù)命名規(guī)矩,從而杜絕css類名沖突的問題。
啊呆同學(xué):CSS Module是不是就是Vue: scoped 樣式的實(shí)現(xiàn)方式呢?
答:不是的,CSS Scope是通過限制作用域來實(shí)現(xiàn),樣式在局部生效,而不是真正意義上的css Module
我們知道,當(dāng)一個(gè)style標(biāo)簽擁有scoped屬性時(shí)候,它的css樣式只能用于當(dāng)前的Vue組件,它的實(shí)現(xiàn)原理是通過PostCSS來實(shí)現(xiàn),通過給想對應(yīng)的dom新增一個(gè)屬性,同時(shí)給css選擇器新增一個(gè)對應(yīng)的屬性,來對應(yīng)這個(gè)唯一的dom,如下所示
而css module 是怎么樣實(shí)現(xiàn)的呢,以vue為例子,如何使用CSS module
- webpack 直接 引入 vue-loader 使用文檔??[1]
- vue-cli3內(nèi)置,可以直接開箱即用, 只需要在style標(biāo)簽標(biāo)記module,就可以在組件內(nèi)使用CSS Modules了,更多操作看文檔使用文檔[2]
下面我們看看CSS Module在vue項(xiàng)目中的編譯效果
我們可以看到,CSS Modules在最終構(gòu)建頁面時(shí)會自動(dòng)重命名class,用vue官方描述就是,這個(gè) module 特性指引 Vue Loader 作為名為 $style 的計(jì)算屬性,向組件注入 CSS Modules 局部對象。然后你就可以在模板中通過一個(gè)動(dòng)態(tài)類綁定來使用它了
啊樂同學(xué):你說CSS Module是 css 模塊化的一種實(shí)現(xiàn)方式,還有其他CSS模塊化實(shí)現(xiàn)方式嗎?
有的,比如BEM 命名規(guī)范,還有下節(jié)會介紹的 CSS in JS
這里簡單介紹下BEM
拓展閱讀:
- CSS Modules 用法教程[3]
- BEM 官方規(guī)范[4]
2. CSS in JS
CSS in JS,顧名思義就是將應(yīng)用的CSS樣式寫在JavaScript文件里面,使用JS語言來寫CSS,包括替代原先寫后綴為.css、.less、.scss等文件
2.1 styled-components
styled-components 是 CSS in JS 實(shí)現(xiàn)方案中比較知名的,大多用于React,通過使用es6語法的標(biāo)簽?zāi)0遄址Z法為component定義css屬性,我們不用在設(shè)置className類名啦~ 我們看看那下面這個(gè)demo
啊雪同學(xué):styled-components是為React而生的,那Vue能使用嗎?
答:可以的,styled-components team 專門為Vue開發(fā)了一個(gè) vue-styled-components,和React的styled-components用法非常相似,有興趣可以玩玩,我玩得不溜(不過這個(gè)倉庫?也是有點(diǎn)少,看來很小眾, style-component寫起來確實(shí)有點(diǎn)別扭)但我始終覺得 CSS-in-JS 會越來越流行 文檔鏈接??[5]
拓展:
styled-components 官網(wǎng)[6]
3.CSS 原子類
其實(shí)這個(gè)概念已經(jīng)很老了,本質(zhì)上也是一種編寫 CSS 的思想,簡而言之就是通過用原子類構(gòu)造選擇器,比如我們定義一個(gè)base.css 文件,里面定義了公共復(fù)用高的選擇器,諸如mgt20(來表示 margin-top: 20px )等等,好處在于便于抽出復(fù)用代碼,提高代碼復(fù)用程度,但是過度的抽象也會帶來了維護(hù)上的巨大成本。
3.1 tailwind
tailwind 官網(wǎng)鏈接[7]其實(shí)本質(zhì)上也是一種原子類思維,一個(gè) class 代表一種 CSS 屬性。優(yōu)點(diǎn)在于它把 class 拆分到足夠細(xì),粒度很小,很好很「原子」。在國外很吃香,因?yàn)樽远x屬性強(qiáng)且類名語義話強(qiáng),你再也不用為取class的名字很犯愁(畢竟單獨(dú)一個(gè)組件開發(fā)我們就可能需要n個(gè)類),自定義就像搭積木一樣,但國內(nèi)爭議比較大,早期原子類在國內(nèi)基本被噴,到2020年后卻態(tài)度有所改觀。我們看下下面這段demo,官方事例如何實(shí)現(xiàn)一個(gè)卡片
我這一眼完全好多類名,但是確實(shí)看起來簡單就能構(gòu)建,但這粒度也太小了吧~問題也隨著暴露,難記,用著用著,你就好比小時(shí)候要拿起字典來查閱單詞,tailwind寶典請查收 查閱鏈接 [8]
輪落地應(yīng)用,當(dāng)前twitter就是基于tailwind進(jìn)行改版的,我們可以在控制臺清晰看到
話說這個(gè)實(shí)驗(yàn)室還蠻有錢,贊助了vite的廣告位
拓展閱讀:
- 如何評價(jià)CSS框架TailwindCSS?[9]
3.2 bulma
Bulma 是一個(gè)基于 Flexbox 布局技術(shù)的免費(fèi)、開源的現(xiàn)代 CSS 框架,早期接觸的時(shí)候是在社區(qū)看到基于Bulma的Vue.js的輕量級UI組件buefy。它完全基于CSS,不需要javascript。這也是他跟boostrap的最大區(qū)別。不過現(xiàn)在也不是很主流,這里不做過多闡述,感興趣同學(xué)可以深入了解,可以看下面這個(gè)例子
學(xué)習(xí)使用CSS框架并不是最終目的,它只是一個(gè)提升生產(chǎn)力的工具,工具的目的是用來提升我們開發(fā)效率,最終賦能到我們的產(chǎn)品中去,所以不用太糾結(jié)有沒有使用過這些框架,畢竟那么多個(gè)框架你是不可能每個(gè)都會用。換句話講了解原理也是可以的, 能提升自己的認(rèn)知
拓展閱讀:
- CSS 框架 Bulma 教程[10]
- https://buefy.org/[11]
4.CSS Sandbox(沙盒)
css沙盒簡而言之就是起到樣式隔離的作用,互不干擾,前端接觸比較多的就是微前端了,畢竟要保證每個(gè)集成進(jìn)來的應(yīng)用樣式互不干擾。因?yàn)閼?yīng)用可能是不同團(tuán)隊(duì)成員開發(fā),正常是會有類名沖突的情況出現(xiàn)。
最早期的實(shí)現(xiàn)方式應(yīng)該就是iframe了,iframe自帶天然隔離,但是這種方式局限性也很多,還有就像上文我們提及的幾個(gè)點(diǎn),比如
- scoped CSS:通過定義屬性scoped來就能結(jié)合 DOM 樹限制 CSS 作用范圍
- CSS in js 及 CSS Module 是通過工具把樣式編譯成腳本
- 移除head內(nèi)標(biāo)簽:這也是qiankun(微前端框架) 的 css 沙箱的原理,通過記錄子項(xiàng)目運(yùn)行時(shí)新增的 style/link 標(biāo)簽,卸載子項(xiàng)目時(shí)移除這些標(biāo)簽。重新添加新載入子項(xiàng)目的標(biāo)簽來實(shí)現(xiàn)
- shadow DOM:你可以理解為dom中的dom,是 Web components一個(gè)重要屬性,它允許將隱藏的 DOM 樹附加到常規(guī)的 DOM 樹中,弊端就是兼容性較差,你可以看下兼容情況??[12]
拓展閱讀:
- 使用 shadow DOM[13]
Reference
[1]使用文檔
https://vue-loader.vuejs.org/zh/guide/css-modules.html#%E7%94%A8%E6%B3%95
[2]使用文檔?
https://cli.vuejs.org/zh/guide/css.html#css-modules
[3]CSS Modules 用法教程:
http://www.ruanyifeng.com/blog/2016/06/css_modules.html
[4]BEM 官方規(guī)范:
http://getbem.com/
[5]文檔鏈接
https://github.com/styled-components/vue-styled-components
[6]styled-components 官網(wǎng):
https://styled-components.com
[7]官網(wǎng)鏈接:
https://www.tailwindcss.cn/
[8]查閱鏈接 :
https://tailwindcss.com/docs/border-radius
[9]如何評價(jià)CSS框架TailwindCSS?:
https://www.zhihu.com/question/337939566
[10]CSS 框架 Bulma 教程:
http://www.ruanyifeng.com/blog/2017/10/bulma.html
[11]https://buefy.org/:
https://buefy.org/
[12]兼容情況:
https://www.caniuse.com/?search=shadow%20DOM
[13]使用 shadow DOM:
https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Using_shadow_DOM