跳至內容

比較

PikaCSS 與其他建置時期樣式工具之間的關係,以及在什麼情況下它是(或不是)正確的選擇。

誠實的定位

PikaCSS 目前仍在 1.0 之前,API 尚未穩定。下面其他工具更為成熟,也擁有更大的生態系。這份比較著重在撰寫模型與引擎設計,而不是哪個專案「比較好」。競品的描述整理自各專案自己文件中的定位;最新細節請查閱它們的文件。

概覽

PikaCSSUnoCSSTailwind CSSPanda CSSvanilla-extract
撰寫語法直接寫在元件裡的 CSS-in-JS 物件:pika({ color: 'red' })寫在標記裡的 utility class 名稱(外加 attributify 與其他 preset)寫在標記裡的 utility class 名稱元件裡的 CSS-in-JS 函式(css()、recipe),會靜態擷取放在獨立 .css.ts 檔案裡的 CSS-in-TS
執行階段成本無:每一次呼叫都會在建置時期替換成 class 名稱字串常值無:CSS 在建置時期產生無:CSS 在建置時期產生CSS 在建置時期產生;由一個輕量的 JS 執行階段負責組合 class 名稱靜態樣式無成本;動態值可選用執行階段輔助工具
動態值不能放在引數裡:請改用 variant map 或 CSS 變數class 名稱必須能靜態偵測到class 名稱必須能靜態偵測到靜態擷取;執行階段值透過 CSS 變數透過 assignInlineVars 使用 CSS 變數
SSR不需要特殊處理:輸出是一個 靜態 CSS 檔案靜態 CSS 輸出靜態 CSS 輸出靜態 CSS 輸出靜態 CSS 輸出
型別安全產生出來的型別會驅動 IDE 對屬性、選擇器與 shortcut 的自動完成;同時仍接受任意字串class 名稱是純字串;有提供 IDE 擴充功能class 名稱是純字串;有提供 IDE 擴充功能為 token 與 recipe 產生型別具備強型別的樣式物件
成熟度1.0 之前,API 尚未穩定成熟,廣泛使用非常成熟,生態系龐大成熟成熟

真正的差異在哪裡

CSS-in-JS 撰寫、atomic CSS 輸出

utility class 工具(UnoCSS、Tailwind CSS)要求你學習並輸入它們的 class 詞彙。PikaCSS 則是把單純的 CSS 屬性名稱保留在 JavaScript 物件裡(與行內樣式或 styled-components 相同的心智模型),並且一樣會輸出去除重複後的原子 class。見 pika() 如何運作

簡寫屬性/個別屬性(longhand)的層疊衝突由引擎解決

atomic CSS 有一個結構性問題:當 paddingpadding-top 的 class 落在同一個元素上時,勝出者是由樣式表順序決定,而不是由你的意圖決定。其他生態系裡存在執行階段的 class 合併工具,用來繞過這個問題。

PikaCSS 則是在建置時期解決它:引擎會追蹤重疊的屬性效果,並保證覆寫用的宣告一定會渲染在它所覆寫的宣告之後,若重複使用舊的 class 會破壞這個順序,就改為建立一個新的 class(packages/core/src/atomic-style.tspackages/core/src/property-effects.ts)。

ts
const className = pika({
	padding: '10px',
	paddingTop: '20px',
})
css
@layer utilities {
  .pk-a {
    padding: 10px;
  }
  .pk-b {
    padding-top: 20px;
  }
}

真正的零執行階段成本,連函式本身也是

pika() 在執行階段並不存在。建置外掛會把每一次呼叫替換成最終產生的 class 名稱字串常值,因此完全不會有任何樣式函式庫送到瀏覽器。採用 css() 風格 API 的工具同樣會在建置時期產生 CSS,但函式本身通常仍會在瀏覽器裡執行以組合 class 名稱;utility class 工具則打從一開始就沒有執行階段的函式。

取捨:只能用靜態引數

由於呼叫是在建置時期求值,引數必須是自足的常值:不能有變數、條件式,或對外層值的 spread。這與 Tailwind「不要動態組合 class 名稱」的規則屬於同一類限制,只是表現在函式呼叫的層級上。動態樣式 涵蓋了支援的各種模式。

何時不該使用 PikaCSS

  • 你現在就需要穩定的 1.0 API 以及長期的遷移保證。
  • 你依賴一個龐大的生態系,裡面有大量綁定特定 class 詞彙的預先建置 UI 元件。
  • 你的樣式大多是 CSS 變數無法表達、真正在執行階段計算出來的值。

下一步