UnoCSS是一款原子化的即時按需 CSS 引擎,其中沒有核心實用程序,所有功能都是通過預設提供的。默認情況下UnoCSS應用通過預設來實現相關功能。
UnoCSS中文文檔:
https://www.unocss.com.cn
前有很多種原子化的框架,例如 Tailwind CSS,Windi CSS 以及 Tachyons 等。
為什么要原子化 CSS?
- 不知道怎么取類名,應該叫什么名字呢,該怎么統一
- CSS頁面樣式太多,每次一個頁面要新寫一個重復類,自己都不記得有哪些類了
- Style文件和頁面文件來回反復橫跳新增全局樣式,太麻煩
傳統方式可能會使用比如 scss 預處理器生成自己想要的 class 類,如下所示:
@for $i from 1 through 10 {.m-#{$i} {margin: $i px;}
}
// 結果為:
.m-1 { margin: 1 px; }
.m-2 { margin: 2 px; }
/* ... */
.m-10 { margin: 10 px; }
上述方式會產生很多場景下可用的 class,可以涵蓋很多場景,但是其中也會有很多種并不會被使用到,從而了導致大量的冗余;因此原子化 CSS 中對于這個也進行了優化,通過按需加載的理念進行預設等方式減少 CSS 的打包體積;
相比原始寫法,應用原子化 CSS 可以減少很多 CSS 的書寫工作,減少每次新增一個新的樣式而重復新增的代碼,比如一個項目中 flex 和 margin 配置一般都會重復寫很多次,使用原子化 CSS 不用重新去寫這些樣式,直接綁定相對應的 class 類名就可以起到同樣的效果,因此減少了項目整體的代碼行數量和無用的工作量。
總的來說原子化 CSS 可以減少 CSS 的體積,同時提高 CSS 類的復用率,減少類名起名的復雜度;但是由于多種 CSS 樣式堆積,可能會造成 class 名過長的缺點;同時增加記住 CSS 樣式的記憶成本;
那么目前哪些人在使用原子化 CSS 呢?
一些網站已經開始使用原子化 CSS 比如 github , swiper.js 等↓如下圖所示,他們頁面的 CSS 類型可以明顯看出是使用了原子化 CSS
一種原子化 CSS 框架 - UnoCss
UnoCSS 是一個引擎,而非一款框架,因為它并未提供核心工具類,所有功能可以通過預設和內聯配置提供;
UnoCSS 中文官網鏈接:
https://www.unocss.com.cn/
原子化 CSS 的概念
所謂 原子化 CSS ,指的是一種用于CSS的架構方式的理念,它傾向于 用途單一的 class,并 以視覺效果進行命名。例如 bootstrap 的顏色系統,為我們提供了直觀的顏色名稱:
我們可以將這些名稱以相似的命名方式構建 css 類:
// Background color
.bg-blue-100 { background-color: $blue-100 }
.bg-blue-200 { background-color: $blue-200 }
.bg-blue-300 { background-color: $blue-300 }
.bg-blue-400 { background-color: $blue-400 }
.bg-blue-500 { background-color: $blue-500 }
.bg-blue-600 { background-color: $blue-600 }
.bg-blue-700 { background-color: $blue-700 }
.bg-blue-800 { background-color: $blue-800 }
.bg-blue-900 { background-color: $blue-900 }
// Font color
.ft-blue-100 { color: $blue-100 }
.ft-blue-200 { color: $blue-200 }
.ft-blue-300 { color: $blue-300 }
.ft-blue-400 { color: $blue-400 }
.ft-blue-500 { color: $blue-500 }
.ft-blue-600 { color: $blue-600 }
.ft-blue-700 { color: $blue-700 }
.ft-blue-800 { color: $blue-800 }
.ft-blue-900 { color: $blue-900 }
// margin
.m-1 { margin: 0.25 rem; }
.m-2 { margin: 0.5 rem; }
.m-3 { margin: 0.75 rem; }
.m-4 { margin: 1 rem; }
.m-5 { margin: 1.25 rem; }
.m-6 { margin: 1.5 rem; }
.m-7 { margin: 1.75 rem; }
.m-8 { margin: 2 rem; }
.m-9 { margin: 2.25 rem; }
我們可以很直觀地使用和調整這些變量值來滿足我們實際開發中的需求,同時我們可以通過動控制 DOM 的樣式來輕松地對效果進行切換,這在 一些現代前端框架(如vue)中,都可以有很絲滑的體驗。
這個例子中的變量為 scss/sass(Sass) 變量,Sass 是目前最強大的前端樣式預編譯語言,本文在后文中也會有一些涉及它的內容。如果你只會 css,或者還在使用 Less(另一種流行的預編譯語言),那么建議你盡早學一下 scss 語法,這十分強大方便,bootstrap、elementPlus 等等多數當前主流框架早以切換到其構建樣式系統。
為什么推薦原子化 CSS
那么為什么要原子化呢。很顯然是讓代碼更 直觀可讀。另外一方面,從設計師的角度出發,如果我們拿到下面這個語義化的外邊距變量名:
.p-1 { margin: 0.25 rem; }
.p-2 { margin: 0.5 rem; }
/* ... */
.p-9 { margin: 2.25 rem; }
完全就可以對照著呈現效果自己手動更改變量來完成效果切換!
原子化 CSS 的實現實踐
如何才能具備原子化的理念的,實現方法有很多。在一個大項目中為了原子化 CSS,。可以先 提供所有你可能需要用到的 CSS 工具,例如 外邊距的大小工具——我們需要約定好一套規范,就像前面的代碼那樣,使用 p 表示 padding 的簡寫,使用 數字 1、2、3、… 表示基值的倍數,這里約定基值為 0.25 rem 。
很顯然在現實項目中通過手動列舉 CSS 類名并逐個描述來完成一套這樣的約定是麻煩的,比如在這種情況下為了盡可能簡單一點我們會使用 root 為元素中定義一些CSS變量——它們會在不同的原子類中反復用到:
:root {--blue-100: #CEE1FE;--blue-200: #9DC3FC;--blue-300: #69A1F3;--blue-400: #3C89FA;--blue-500: #0D6DFB;--blue-600: ##0A58CA;--blue-700: #084297;--blue-800: #052C65;--blue-900: #031633;--rsize-1: 0.25 rem;--rsize-2: 0.5 rem;--rsize-3: 0.75 rem;--rsize-4: 1 rem;--rsize-5: 1.25 rem;--rsize-6: 1.5 rem;--rsize-7: 1.75 rem;--rsize-8: 2.00 rem;--rsize-9: 2.25 rem;
}
然后施展原子css我們的優勢了:
// Background color
.bg-blue-100 { background-color: var(--blue-100) }
.bg-blue-200 { background-color: var(--blue-200) }
// ...
.bg-blue-900 { background-color: var(--blue-200) }
// Font color
.ft-blue-100 { color: var(--blue-100) }
.ft-blue-200 { color: var(--blue-200) }
// ...
.ft-blue-900 { color: var(--blue-900) }
// Margin
.m-1 { margin: var(--rsize-1) }
.m-2 { margin: var(--rsize-1) }
// ...
.m-9 { margin: var(--rsize-9) }
使用預編譯語言
這樣是不是依然很麻煩——好在我們可以通過編程來完成。
由于 css 自身并沒有這樣的能力,以前不得不借助其它語言來生成這樣的東西,但如今我們可以使用 如 Sass、Less 這樣的預處理器來實現。例如生成 10
p-1、p-2、…、p-9,我們可以使用 @for 指令:
@for $i from 1 through 9 {.m-#{$i} {margin: $i / 4 rem;}
}
上面的 @for 指令可以在限制的范圍內重復輸出格式,其語法格式為:
@for $var from <start> through <end> {// ... style
}
或者
@for $var from <start> to <end> {// ... style
}
其中:
? KaTeX parse error: Expected '}', got 'EOF' at end of input: …是迭代變量,可以在塊內通過 {var} 的格式來引用;
? 當使用 through 時,條件范圍包含 與 的值,而使用 to 時條件范圍只包含 的值不包含 的值;
? 必須是整數值。
對于顏色值的計算和處理要復雜一些,我們需要用到一些 Sass 內置的一些顏色處理函數,例如 mix、adjust-hue、change-color、scale-color、desaturate、transparentize等等
總結感受:
在使用 UnoCSS 的過程中,感受到了不用寫 的快樂,不用來回穿插 CSS 文件和 VUE 文件,CSS 類名隨手就寫上,想要什么樣式往上堆積就行,還不用去絞盡腦汁的去想起什么類名,帶來了很多便捷的地方;但是也存在一定的困難點,就是會造成無法快速定位樣式問題的困惑;