幾天前,我在一個前端社群看見版友(或說作者本人)分享了 Master Styles,一個基於 Virtual CSS 概念的 CSS 框架,由於首次聽到 Virtual CSS 這個新穎的詞彙,加上他是由台灣人撰寫,就懷著好奇的心花了點時間研究及體驗。
Virtual CSS
關於 Vitrual CSS,作者在文件中提及:
『Virtual CSS is the concept of expressing CSS rules through class syntax.』
照翻就是:Virtual CSS 是一種藉由 Class 語法來表達 CSS 規則的概念
其原理就是將一個虛擬的樣式表保存在記憶中,並即時與實際的 CSS 樣式表同步,核心是使用 Mutation Observer,會觀察 DOM 樹並透過一個特殊的規則引擎去遍歷每個 class,將其轉換為 CSS 並注入至 style。
Why
每個框架/函式庫/工具的誕生都是為了解決一個以上痛點,Master Styles也不意外。以下是我參閱了官方文件並加入了一點自己的看法作為超譯。
相較 Master Styles,其他 CSS 開發時可能碰到的痛點:
過早的抽象化
除非有非常充裕的時間,通常在開發時較難找出每個區塊樣式的共同點和重複的部分,如果前期就大量進行了不準確的抽象化,容易降低頁面配合需求變動的靈活性,若樣式大量被使用也可能會有修改不便甚至改A壞B的隱憂。
取名的時間成本
假設我們要為一個樣式命名,通常我們會看:
- 這個區塊應該被稱為什麼?
- 先來看看內容有些什麼…
- 好,看起來像是 xxx
// style.css
.xxx {
font-size: 24px;
/* ... */
}
可能只是幾行 CSS,幾分鐘就過去了。
維護專案 CSS 所在的時間成本
在維護專案時,尋找 CSS 容易耗費額外的時間,通常需要仰賴瀏覽器 devtool 和編輯器的搜尋功能來降低尋找時間。
入門時的學習曲線高
常見的樣式開發技術如 CSS-in-JS、Atomic CSS 本身都有自己的學習曲線,即使是使用傳統的 CSS 建構的專案,首次進入時也得花時間閱讀專案文件或靠自己觀察出 CSS 的檔案架構。
CSS-in-Class
對於這些問題,在使用 CSS in Class 進行開發時,
- 無須抽象化,直接寫就對了
- 寫出像是 CSS 的 class 名稱
- 不必查找大量 CSS 花費額外時間成本
- 學習曲線低
導入
CDN 範例
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://unpkg.com/@master/normal.css" rel="stylesheet">
<script src="https://unpkg.com/@master/style"></script>
<script src="https://unpkg.com/@master/styles"></script>
</head>
<body>
<h1 class="font:40 font:heavy font:italic m:50 text:center">Hello World</h1>
</body>
不需要 Webpack、不需要任何額外打包工具,就是這麼單純。
亦可藉由 NPM 安裝:
// 安裝指令
npm install @master/styles @master/normal.css// 引入
import '@master/styles';
@import '@master/normal.css';
以下是截至官方文件的範例:
語法範例1
<p class="text-align:center font-size:1rem background-color:red-50">Lorem ipsum dolor sit amet.</p>
有學習過 CSS 的應該不難猜出,三個 class 分別套上了置中、文字大小及背景色。
覺得寫法太長?試試更簡潔的:
<p class="text:center font:16 background:red-50">Lorem ipsum dolor sit amet.</p>
再來個更簡潔的:
<p class="t:center f:16 bg:red-50">Lorem ipsum dolor sit amet.</p>
三種寫法都能得到相同的結果。
語法範例2 — 可給予多個值的屬性
Master Styles 以分號做為區隔多個值的屬性樣式,例如:
<p class="animation:fade;1s;ease transition:opacity;.3s margin:16;32;16;40">Lorem ipsum dolor sit amet.</p>
animation:fade;1s;ease
代表了 animation: fade 1s ease
;transition:opacity;.3s
代表了 transition: opacity 0.3s
;而 margin:16;32;16;40
則代表了 margin: 16px 32px 16px 40px
。
覺得太長嗎?試試這個:
<p class="@fade;1s;ease ~opacity;.3s m:16;32;16;40">Lorem ipsum dolor sit amet.</p>
作者對於 animation 以 @ 作為簡寫,~ 作為 transition 簡寫也寫出自己如此設計的原因,有興趣可參考官方文件。
其他寫法如 !important、偽元素、偽類別、calc、var、斷點等等的寫法,在官方文件中都有詳細敘述及範例,我這邊就不再贅述。
樣式複用
當專案慢慢變大,需要對樣式進行複用時,就必須仰賴打包工具進行輔助,以 Vue Cli 和 create-react-app 為例:
// 兩個架構都使用同路徑及內容
// src\classes\outline-button.js
export const OUTLINE_BUTTON_CLASS = `
b:1px;solid;#000 p:12 r:4 bg:aqua bg:navy:hover color:#fff:hover ~all;300ms;ease
`;
// -----------------------------------------------------------
// Vue (以Vue Cli為例)
// some-random-component.vue
<template>
<div>
<button :class="OUTLINE_BUTTON_CLASS">Hover me!</button>
</div>
</template><script>
import { OUTLINE_BUTTON_CLASS } from "../classes/outline-button";
export default {
name: "HelloWorld",
data() {
return {
OUTLINE_BUTTON_CLASS: OUTLINE_BUTTON_CLASS,
};
},
};
</script>// main.js
import "@master/normal.css";
import "@master/styles";// -----------------------------------------------------------
// React (以create-react-app為例)
// src/App.js
import { OUTLINE_BUTTON_CLASS } from "./classes/outline-button";
import "./App.css";function App() {
return (
<div className="App">
<button className={OUTLINE_BUTTON_CLASS}>Imma leave my door open</button>
</div>
);
}export default App;// index.js
import "@master/normal.css";
import "@master/styles";
(關於樣式複用,官方文件目前看起來還沒有很清楚的說明,如果未來有補充了還煩請打臉我的寫法,感謝!)
個人心得
在大致閱讀了官方文件並到 Frontend Mentor 找了一個小專案來切版後,專案的原始碼我會放在最下方。大致分享一些心得。
優缺點及適合場景
優點
- 非常輕量,CDN所需的資源總容量不超過13KB
- 極低的導入成本,可不依賴打包工具
- 可與其他 CSS 框架並行(須注意原本專案是不是就有 reset.css 或 normalize.css)
缺點
- 核心需仰賴 JavaScript 驅動,在不允許 JS 的瀏覽器會完全失效
- 複用樣式需要仰賴打包工具,部分架構如 Laravel 目前尚不知複用架構的做法,且若複用樣式相較傳統 CSS 寫法我覺得沒那麼好
- 尚無法完全捨棄 <style> 或 .css,如若需要自定義 keyframes 或 CSS 變數依然需要用原生的寫法寫
- 若標籤的樣式過多,可能造成可讀性差的問題
適合
- 走快速開發且注重載入效能的頁面
- 沒有 Webpack 或其他打包工具的專案
不適合
- 需支援舊瀏覽器的頁面
- 已有高度模組化 CSS 的專案
可嘗試的情境
- 一次性的活動頁
- 小型專案
使用體驗
使用上提供的小專案切版作為體驗,在沒有任何 CSS 包袱情況下,我個人覺得寫起來蠻爽的,尤其是簡寫部分,以往要移動滑鼠去開啟 style.css 的時間就已經寫好一個 HTML 元素所需的樣式,我個人也非常喜歡 var 的簡寫:
<div class="h:$(size)">Guess my height!</div>
看著就覺得滿優雅的。
但就如同上面所述,我覺得最適合它的場景沒有很多,但框架、技術、工具都是很主觀的,實際體驗才會知道適不適合,且這個專案是去年年底才釋出 Alpha 版,實際年齡可能連一歲都不到,官方文件也有很多還在撰寫的地方,我個人是很看好它的未來的。
關於 Master Styles 的體驗心得就記錄到這,希望能幫助到正在觀望的人,與其觀望,不如找個版型切切看吧!
實際切版頁面
及原始碼:
References: