JSS 是什么
簡單來說,一句話概括CSS in JS (JSS),就是"行內樣式"(inline style)和"行內腳本"(inline script),
因為,自從React出現以后,基于組件化的要求,強制把HTML、CSS、JavaScript捆綁在一起,在同一個檔案里面,封裝了結構、樣式、以及邏輯,這雖然違背html發明初期的"關注點分離"的原則,但更有利于組件之間的隔離,而每個組件包含了所有需要用到的代碼,不必依賴外部環境,組件之間沒有耦合,所以,隨著 React 的走紅和組件模式深入人心,“關注點分離”原則越發淡出人們的視野,而React所帶來的"關注點混合"的原則逐漸成為主流,[1]
React 對 CSS 封裝非常簡單,就是沿用了 DOM 的 style 屬性物件,CSS-in-JS是一種技術(technique),而不是一個具體的庫實作(library),簡單來說CSS-in-JS就是將應用的CSS樣式寫在JavaScript檔案里面,而不是獨立為一些.css,.scss或者less之類的檔案,這樣你就可以在CSS中使用一些屬于JS的諸如模塊宣告,變數定義,函式呼叫和條件判斷等語言特性來提供靈活的可擴展的樣式定義,值得一提的是,雖然CSS-in-JS不是一種很新的技術,可是它在國內普及度好像并不是很高,它當初的出現是因為一些component-based的Web框架(例如React,Vue和Angular)的逐漸流行,使得開發者也想將組件的CSS樣式也一塊封裝到組件中去以解決原生CSS寫法的一系列問題,還有就是CSS-in-JS在React社區的熱度是最高的,這是因為React本身不會管用戶怎么去為組件定義樣式的問題,而Vue和Angular都有屬于框架自己的一套定義樣式的方案,[2]
JSS 的常見實作
由于React 對 CSS 的封裝非常弱,導致出現了一系列的第三方庫,用來加強 React 的 CSS 操作,它們統稱為 CSS in JS,意思就是使用 JS 語言寫 CSS,根據不完全統計,各種 CSS in JS 的庫至少有47種,老實說,現在也看不出來,哪一個庫會變成主流,[1]
1. Styled-components
缺點:
- 必須使用Styled-components預定義的語法糖,如
styled.div("...") - 語法糖對css的封裝居然使用的是string,而使用string也就意味著我們將會失去一切可能的物件化操作css的機會,這與差不多10年前
AngularJS 1.x時代對 html 的處理方法如出一轍,不得不說這種方式似乎是在開歷史的倒車,
不過,Styled-components 應該是CSS-in-JS最熱門的一個庫了,到目前為止github的star數已經超過了30k了,通過styled-components,你可以使用ES6的標簽模板字串語法(Tagged Templates)為需要styled的Component定義一系列CSS屬性,當該組件的JS代碼被決議執行的時候,styled-components會動態生成一個CSS選擇器,并把對應的CSS樣式通過style標簽的形式插入到head標簽里面,動態生成的CSS選擇器會有一小段哈希值來保證全域唯一性來避免樣式發生沖突,[2]
它既具備了 css-in-js 的模塊化與引數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本[3],
Styled-components官網,
2. CSS module
import style from './index.css'
<div className={style.app}>
需要額外配置,ts環境需要配置*.d.ts的型別宣告檔案
declare module "*.css" {
const css: {
[key: string]: string //約定:匯出key所在的物件,原始的類名和內容都會和轉化為這個物件
};
export default css;
}
JSS 的好處
p.s. 接下來內容均轉自 知乎/進擊的大蔥/CSS in JS的好與壞,
1. 區域樣式 - Scoping Styles
CSS有一個被大家詬病的問題就是沒有本地作用域,所有宣告的樣式都是全域的(global styles),而CSS-in-JS會提供自動區域CSS作用域的功能,你為組件定義的樣式會被限制在這個組件,而不會對其他組件的樣式產生影響,[2]
2. 避免無用的CSS樣式堆積
進行過大型Web專案開發的同學應該都有經歷過這個情景:在開發新的功能或者進行代碼重構的時候,由于HTML代碼和CSS樣式之間沒有顯式的一一對應關系,我們很難辨認出專案中哪些CSS樣式代碼是有用的哪些是無用的,這就導致了我們不敢輕易洗掉代碼中可能是無用的樣式,這樣隨著時間的推移,專案中的CSS樣式只會增加而不會減少(append-only stylesheets),
而因為CSS-in-JS會把樣式和組件系結在一起,當這個組件要被洗掉掉的時候,直接把這些代碼洗掉掉就好了,不用擔心刪掉的樣式代碼會對專案的其他組件樣式產生影響,而且由于CSS是寫在JavaScript里面的,我們還可以利用JS顯式的變數定義,模塊參考等語言特性來追蹤樣式的使用情況,這大大方便了我們對樣式代碼的更改或者重構,[2]
3 Critical CSS
放在head標簽內的CSS當然是越少越好,因為太多的內容會加大html的體積,所以我們一般把用戶需要在首屏看到的(above the fold)頁面要用到的最少CSS提取為Critical CSS,
CSS-in-JS通過增加一點加載的JS體積就可以避免另外發一次請求來獲取其它的CSS檔案,而且一些CSS-in-JS的實作(例如styled-components)對Critical CSS是自動支持的,[2]
4. 基于狀態的樣式定義
CSS-in-JS可以根據組件的狀態動態地生成樣式,[2]
5. 封裝得更好的組件庫
如果CSS是寫在JS里面的,專案想要使用封裝的組件庫只需要進行簡單的npm install就可以了,非常方便,[2]
JSS 的壞處
p.s. 接下來內容均轉自 知乎/進擊的大蔥/CSS in JS的好與壞,
1. 陡峭的學習曲線
首先CSS-in-JS是針對component-based的框架的,這就意味著要學習CSS-in-JS你必須得學習:component-based框架(例如React),JavaScript和CSS這三樣技能,其次,即使你已經會用React,JavaScript和CSS來構建SPA應用,你還要學習某個CSS-in-JS實作(例如styled-components),以及學習一種全新的基于組件定義樣式的思考問題方式,[2]
2. 運行時消耗
由于大多數的CSS-in-JS的庫都是在動態生成CSS的, 這就意味著會有一定的性能代價[2]
3. 代碼可讀性差
大多數CSS-in-JS實作會通過生成唯一的CSS選擇器來達到CSS區域作用域的效果,這些自動生成的選擇器會大大降低代碼的可讀性,給開發人員debug造成一定的影響,[2]
4. 沒有統一的業界標準
CSS-in-JS只是一種技術思路而沒有一個社區統一遵循的標準和規范,所以不同實作的語法和功能可能有很大的差異,[2]
總結
CSS-in-JS有好處也有壞處,要不要使用完全取決于同學們自己的專案需求,例如在下面幾種情況下你就不需要它:
- 前端開發的初學者: 由于CSS-in-JS的學習坡度很陡,剛開始學習Web開發的同學沒必要學習,可能會有挫敗感,
- 功能簡單的靜態頁面:邏輯互動不復雜的網站沒有必要使用CSS-in-JS,
- 注重樣式可讀性以及除錯體驗: CSS-in-JS動態生成的選擇器很影響代碼的可讀性,可能會降低你的除錯效率,
在我們的課程中,我們CSS-in-JS和普通的css我們都會使用,所以請同學們放心,進過本課程的學習,同學們基本上能掌握如何使用不同的方式來定義React的樣式了,
參考文獻
- [1] 阮一峰的網路日志/CSS in JS 簡介
- [2] 知乎/進擊的大蔥/CSS in JS的好與壞
- [3] Styled Components: Enforcing Best Practices In Component-Based Systems
- [3] JSS
- [4] wikipedia
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/548376.html
標籤:其他
