<!-- .slide: data-transition="fade" --> ## 前言 --- ### 對你而言, - 編寫樣式是件苦差事 ? - 經常覺得 CSS 很難使用 ? - 認為樣式很難被 Debug ? - 專案中充斥著難被理解的CSS類 ? --- 擁有這樣想法的你並不孤單, 也許你也該試試 TailwindCSS, 接下來,我將透過幾個情境, 向你解釋它怎麼面對這些問題。 --- <!-- .slide: data-transition="fade-in" --> ## 迷人的 TailwindCSS 分享者: Nilson Weng --- <!-- .slide: data-transition="zoom-in" --> ### 情境一 因為不同瀏覽器所默認的樣式行為有 所不同,例如,行高、邊距和標題字 體大小等。因此,需要設置樣式重置 表覆蓋的既有樣式效果,避免差異。 --- 因為不確定所用的重置樣式表方案, 是 [Reset CSS](https://meyerweb.com/eric/tools/css/reset/),還是 [Normalize.css](https://github.com/necolas/normalize.css) 呢? 在開始工作前你得先查閱舊專案。 ![image](https://hackmd.io/_uploads/r1cK8yMT2.png) --- 重置樣式表總是佔據樣式表最上方。 ![image](https://hackmd.io/_uploads/ryFurJf6n.png) --- <!-- .slide: data-transition="fade" --> ### Tailwind @tailwind base 會自動注入這些樣式 ```css @tailwind base; /* Preflight will be injected here */ @tailwind components; @tailwind utilities; ``` --- <!-- .slide: data-transition="zoom-in" --> ### 情境二 - ## 完成 ChitChat 對話視窗 ![image](https://hackmd.io/_uploads/Bk27yxfT2.png) --- <!-- .slide: data-transition="fade" --> ### 使用 CSS - 分析元件,產生 html 結構 (3 min) - 建立 .css 檔案,並引入專案。(2 min) - 思考樣式類的命名方式,(2 min) - 創建樣式類的區塊、組織結構,(5 min) - 在對應的區塊中填入 CSS,(5 min) 檢查效果是否符合預期。(3 min) 費時: 20 分鐘 --- <!-- .slide: data-transition="fade" --> ### 使用 Tailwind - 分析元件,產生 html 結構 (3 min) - ~~建立 .css 檔案,並引入專案。 (2 min)~~ - ~~思考樣式類的命名方式,(2 min)~~ - ~~創建樣式類的區塊、組織結構,(5 min)~~ - **在 html 中填入 tailwind 類,(4 min)** 檢查效果是否符合預期。(3 min) 費時: 10 分鐘 --- - 使用 CSS 完成的效果 ![image](https://hackmd.io/_uploads/ryQhnyzah.png) --- - 使用 Tailwind 完成的效果 ![image](https://hackmd.io/_uploads/HkG0hyzah.png) --- ### [css vs tailwind](https://planflow.dev/blog/the-main-advantage-of-tailwindcss) ![image](https://hackmd.io/_uploads/H1DnTEz6h.png) --- <!-- .slide: data-transition="zoom-in" --> ### 情境三 - #### 請問以下Hex值,分別代表什麼顏色? - (紅、綠、藍、黃?要猜猜看嗎?) ```css { background-color: "#93c5fd" } { background-color: "#bfdbfe" } { background-color: "#dbeafe" } { background-color: "#eff6ff" } ``` --- 你需要一個 [Color Picker](https://www.w3schools.com/colors/colors_picker.asp) 來確認顏色的 hex 值、rgb 值。 ![image](https://hackmd.io/_uploads/rJvamxM63.png) --- ### Tailwind - 預設讓顏色採色階方式定義 - 能有效辨識出顏色色系、深淺 - 如 bg-cyan-100、text-sky-300。 ![image](https://hackmd.io/_uploads/H1oPNxf6h.png) --- ### 誰更容易理解與維護 ? CSS ```css { background-color: "#93c5fd" } { background-color: "#bfdbfe" } { background-color: "#dbeafe" } { background-color: "#eff6ff" } ``` Tailwind ```htmlembedded <div class="bg-blue-50"></div> <div class="bg-blue-100"></div> <div class="bg-blue-200"></div> <div class="bg-blue-300"></div> ``` --- ### 情境四 <!-- .slide: data-transition="zoom-in" --> - 邊距、行高、尺寸、大小。 - 在這裡將透過以下來例子說明: ![image](https://hackmd.io/_uploads/SyeejezT2.png) --- ### 使用 CSS ![image](https://hackmd.io/_uploads/S1EiqeMTn.png) --- ### 使用 Tailwind - 能搭配 IDE 查看實際所對應的 CSS 屬性 ![image](https://hackmd.io/_uploads/HJQNRgzTn.png) --- - ### Tailwind - 邊距、尺寸、大小 - 基本單位是 rem - 邊界的距離使用一般數字,表示級距。 如 p-10、w-2、max-w-1、border-1 - 尺寸使用 sm、md(base)、lg、xl、2xl。 如 text-sm、rounded-md - 亦可使用 **[ ]** 自訂義大小, 如 p-[100px]、text-[16px] --- ### 為何用 rem,px 哪裡不好 ? - px 不夠彈性。 - rem 是相對單位,因應響應式設計需求。 若不同尺寸的螢幕上改變父元素(:root)的 px數值,便可改變所有子元素的單位數值 ``` css /* 默認大小 1rem = 16px*/ :root { font-size: 16px; } ``` --- ### 情境五 <!-- .slide: data-transition="zoom-in" --> - RWD 開發需求 - 繼續使用情境四的例子, 根據畫面寬度改變顏色。 --- ### CSS - 使用 media query 語法 ![image](https://hackmd.io/_uploads/B1ycPZGah.png) --- ### Tailwind - 使用 "`:`" (使樣式於特定條件下觸發效果) ![image](https://hackmd.io/_uploads/rJCqLWzp2.png)(https://play.tailwindcss.com/mSBqQyV4D9) - 預設的尺寸表如下 ![image](https://hackmd.io/_uploads/S1L44PMa2.png) --- ### Tailwind 自定義其他尺寸 ![image](https://hackmd.io/_uploads/S1SJKZGa3.png) --- ### 情境六 - 討厭的前綴 <!-- .slide: data-transition="zoom-in" --> - 某些CSS屬性需要添加特定的前綴, 適應不同瀏覽器之間的差異。 ```css -webkit- /* Chrome、Safari */ -moz- /* Firefox */ -o- /* Opera */ -ms- /* Internet Explorer */ ``` --- ### [Can I Use](https://caniuse.com/) - 你需要查看各瀏覽器的支援情況。 ![Can I Use](https://hackmd.io/_uploads/B1LZoZfan.png) --- CSS - 自行添加這些前綴,既繁瑣,且容易錯誤。 ![image](https://hackmd.io/_uploads/r1BfOSPSR.png) 👉 [Autoprefixer Online](https://autoprefixer.github.io/) --- ### Autoprefixer - Autoprefixer 是一個 PostCSS 插件 - 它能解析當前 CSS 並自動添加這些前綴。 ![image](https://hackmd.io/_uploads/BJAEaZzTh.png) --- ### Tailwind - 高度利用 postcss。 - 採插件型式擴展 Autoprefixer。 ```js // @file: postcss.config.js module.exports = { plugins: { tailwindcss: {}, autoprefixer: {}, }, } ``` --- ### 情境七 - 膨脹的 CSS 體積 <!-- .slide: data-transition="zoom-in" --> - 膨脹的CSS 也是網頁載入緩慢的原因 --- - CSS - 單純CSS開發下, 隨著專案規模擴大, 幾乎不可能避免此問題。 - Bootstrap、Material UI - 即使透過搖樹(tree-shaking)方式, 拆分元件也效果有限。 --- ### PurgeCSS - PurgeCSS 可以刪除未使用的 CSS 代碼, 從而生成更小的 CSS 文件。 ![image](https://hackmd.io/_uploads/ry4RMDDH0.png) #### [purifycss-online](https://purifycss.online) 👈 --- - ### Tailwind - 對比先前的 autoprefixer 需要 postcss.config.js 中配置 - PurgeCSS 是直接內置的, 不需要額外配置。 --- ### Tailwind 工作流程 - 能掃描專案的所有文件,並輸出一份實際有用到的樣式文件。 ![image](https://hackmd.io/_uploads/B1_9YHPBR.png) <!-- ![image](https://hackmd.io/_uploads/B1UtXAoih.png) --> --- <!-- .slide: data-transition="zoom-in" --> ### Tailwind 豐富的生態系 - Editor Support (VSCode、WebStorm、Neovim) - Prettier --- <!-- .slide: data-transition="fade" --> ### VSCode &nbsp; ❤ &nbsp; Tailwind ![image](https://hackmd.io/_uploads/HkMaYBPS0.png) --- ### 完成的效果 - 出現選項視窗 <!-- ![image](https://hackmd.io/_uploads/ByAHoIqnh.png) --> ![image](https://hackmd.io/_uploads/r18RYrwB0.png) - 滑鼠選停在樣式上會出現對應的CSS語法 <!-- ![image](https://hackmd.io/_uploads/ry5N3I5hh.png) --> ![image](https://hackmd.io/_uploads/ByEJ5rDBA.png) --- ### Tailwind 解決 CSS 難題 - 樣式衝突、命名衝突、殭屍樣式(zombies) ![image](https://hackmd.io/_uploads/H1-GqSPHR.png) --- - Tailwind 帶來安全、可靠的開發體驗 ![image](https://hackmd.io/_uploads/H1Rm5rDHA.png) ![image](https://hackmd.io/_uploads/H1nN5BPrR.png) - Tailwind 發現衝突的樣式 --- <!-- .slide: data-transition="fade" --> ### Prettier &nbsp; ❤ &nbsp; Tailwind ![image](https://hackmd.io/_uploads/H1L0CrMph.png) --- ### 完成的效果 - 使團隊中在CSS編寫順序維持一致。 - 減少認知差異,避免誤會與風格混亂。 ![prettier-vscode-demo](https://hackmd.io/_uploads/SyPOjrvS0.gif) --- <!-- .slide: data-transition="zoom-in" --> ### 小結 - 優秀的抽象層設計與豐富的文件。 - 提升人員開發樣式的工作效率。 - 優化樣式文件的可靠度與性能表現。 - 極佳的開發體驗與可維護性。 --- <!-- .slide: data-transition="zoom-in" --> ![tailwind-真香](https://hackmd.io/_uploads/r1VjsBwS0.png) --- <!-- .slide: data-transition="slide-in" --> ### 感謝各位聆聽 --- ## 補充 - 上手安裝 --- ### 如何上手安裝 --- ### Node.js ![](https://hackmd.io/_uploads/SkHcAw2T2.png) --- ### [下載安裝 TailwindCSS](https://tailwindcss.com/docs/installation) - 命令行工具與編譯器(TailwindCSS 核心) ```shell # 創建一個專案 $ mkdir tailwind_project $ cd tailwind_project # 安裝 TailwindCSS $ npm install -D tailwindcss ``` --- ### Tailwind 配置文件 - TailwindCSS 專案初始化建置開發環境 ```shell $ npx tailwindcss init ``` ```js // @file: ./tailwind.config.js /** @type {import('tailwindcss').Config} */ module.exports = { content: ["./src/**/*.{html,js}"], theme: { extend: {}, }, plugins: [], } ``` --- ### Tailwind Preflight - 配置 @tailwind 指令添加到主要得CSS文件中。 - 配置 Tailwind 默認的重置樣式表效果。 ```css /* @file: ./input.css */ /* 假設 input.css 為主要CSS文件 */ @tailwind base; @tailwind components; @tailwind utilities; ``` --- ### Tailwind CLI - 透過命令行工具啟用 Tailwind 工作流程。 - 掃描專案中所有文件中的類來構建 CSS。 ```shell $ npx tailwindcss -i ./input.css -o ./output.css --watch ``` --- ### Tailwind 的 PurgeCSS 機制 - 設置 content 屬性,將影響 Tailwind 掃描的文件範圍。在該範圍之外所輸入的Tailwind類將不會被自動產生出來。 ```js // @file: ./tailwind.config.js /** @type {import('tailwindcss').Config} */ module.exports = { content: ["./src/**/*.{html,js}"], // 👈 (略...) } ``` --- ### Tailwind 工作原理 ![](https://hackmd.io/_uploads/HJ8Igtnpn.png) --- ### Tailwind Build 命令 能產出壓縮過的CSS文件使體積縮小提升性能。 ```shell $ npx tailwindcss build -o ./dist/build.css --minify ``` --- ### 壓縮後的 Tailwind.css - 檔案大小 10.3 kB → 3.83kB (減少 62.8%) - 載入大小 3.5kB → 1.8kB (減少 48.5%) - 載入速度 11ms → 6ms (加快 83%) ![](https://hackmd.io/_uploads/SJ6Xqth6h.png) --- ### CSS to Tailwind 給美術人員或想學習Tailwind的建議 --- ### 建議瞭解 CSS 開始學 - Tailwind 是基於 CSS 而生,因此, 你應先學習 CSS,再去使用它。 - 記憶學習 Tailwind 很簡單,但是, 理解 CSS 特性必不容易。 👉 [CSS to Tailwind Online Tool](https://transform.tools/css-to-tailwind) --- ### Tailwind 基本語法 - 使用 Tailwind CSS 時,首要理解 Variant 和 Utility 之間的關係,並熟悉如何使用它們來構成所需的**組合樣式**。 關係式如下: ```jsx [Variant]:[Utility] - 變量 ( Variant ): - 某個對象、特定條件、狀態等。 - 功能類 ( Utility Class ) : - 則是定義小的、基本的、可重複使用的風格的類。 - 這些類可以組合在一起,以創建複雜的設計。 ``` #### 👉 [tailwindcss-online](https://play.tailwindcss.com/) --- ### Utility Class 範例1 - 一般常見的功能類 👉 [Demo](https://play.tailwindcss.com/e7Sb4lKdYH) ```tsx // bg-pink-400 : 預設情形下,讓設置背景為粉紅色 <div class="p-[100px] bg-pink-400" /> ``` ![](https://hackmd.io/_uploads/ryC2Z3ojh.png) --- ### Utility Class 範例2 - 會根據條件決定的功能類 👉 [Demo](https://play.tailwindcss.com/Jclt3RyCJ6) - media query 語法 ```tsx // bg-pink-400 : 預設情形下,讓設置背景為粉紅色 // 其他根據不同寬度: 產生顏色便換。 // 預設尺寸如: sm、lg、xl、2xl... <div class="p-[100px] bg-pink-400 sm:bg-orange-400 lg:bg-yellow-400" /> ``` --- ### Tailwind 進階課題 給有Tailwind使用經驗的學習者 --- ### Tailwind 進階 - 樣式抽離 ![image](https://hackmd.io/_uploads/ryRXGDPHA.png) --- ### 如何將樣式抽離 -1 可以使用 @apply 來抽離,但是不要濫用 ![image](https://hackmd.io/_uploads/BJGIGvwS0.png) --- ### 如何將樣式抽離 -2 搭配前端框架,Tailwind 可以發揮得更好。 ![image](https://hackmd.io/_uploads/HJiDzvPB0.png) --- ### 如何將樣式抽離 -3 - 注入 bgColor 動態樣式 ![image](https://hackmd.io/_uploads/HJWFfwDSR.png) --- ### 不推薦的使用方式 ⛔ - 使用情境 ![image](https://hackmd.io/_uploads/Hyh5VIDrR.png) - 需設置白名單才能作用 ![image](https://hackmd.io/_uploads/Bk49GDwBA.png) --- ### 較好的使用方式 ✅ ```jsx // Box 是一個簡單的元件,用來顯示一個有背景色的方塊。 const Box = ({ bgColor }) => { return <div className={bgColor}></div>; }; // 使用 tw 來注入背景色 <Box bgColor="bg-red-300" /> ``` --- ### 與 CSS 一起使用 🤝 無法事前就決定的 Tailwind 樣式, 所以,何不直接使用 css 來解決。 ```jsx // 將 CSS 和 Tailwind 一起使用 const Box = ({ bgColor }) => { return <div style={{ backgroundColor: bgColor }}></div>; }; <Box className="p-4" bgColor={'#ff0000'} />; ``` --- ### 如何合併 tailwind 樣式 ? 在開發 tailwind 樣式中,會遇到 需要合併 tailwind 樣式的時候。 <br> 直覺上,你可能會這樣做... ```js <div class={"px-2 py-1 bg-red " + "bg-blue"} /> // ^ 記得留空格 ``` --- 但是,由於樣式的發生順序是根據 樣式表的先後順序來決定,因此, 這裡反而 bg-red 會蓋掉 bg-blue 效果。 ![image](https://hackmd.io/_uploads/rkansLPBA.png) ```js <div class={"px-2 py-1 bg-red bg-blue"} /> ``` --- ### twMerge 為避免這種狀況,與樣式的衝突發生, 可借助 tailwind-merge 庫來進行合併。 ```js import { twMerge } from 'tailwind-merge' twMerge('px-2 py-1 bg-red ', 'p-3 bg-blue') // → 'p-3 bg-blue' ✨ ``` --- ### clsx clsx 函數可以讓你用多種類型,如物件、 陣列、布林值或字串,來組成字串, 借此提升了編寫 tailwind 樣式的彈性。 ```js import { clsx } from 'clsx'; // Strings (variadic) clsx('foo', true && 'bar', 'baz'); //=> 'foo bar baz' ``` --- ### cn = twMerge + clsx ⚔️ - twMerge : 將樣式字串序列進行排序。 - clsx : 幫助合併 tailwind class 成字串序列 ```ts // @file: ./utils/cn.ts import { clsx, type ClassValue } from "clsx" import { twMerge } from "tailwind-merge" export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } ``` --- ### 借助 cn 函式改進元件 ![image](https://hackmd.io/_uploads/HkQaTUDSC.png) 🎞️ [請帥哥教你cn](https://www.youtube.com/watch?v=re2JFITR7TI&list=PLvn_u52ubqUFM8o2RKvI6YyRyppXn36a1&ab_channel=ByteGrad) --- ## cva 主要目的在於創造元件樣式的變體(variants) ![image](https://hackmd.io/_uploads/ryrNQrvHA.png) ##### 👉 [bootstrap 按鈕變體範例](https://getbootstrap.com/docs/5.3/components/buttons/#variants) --- ### 變體 (Variants) 理解上,變體為元件的差異化種類。用神奇寶貝 來說,就像是"色微"的感覺。仍屬於原來物種, 能力一致,但在外型上卻有所差異。 ![image](https://hackmd.io/_uploads/H167ErPSA.png) --- ### cva 的結構 - variants - compoundVariants - defaultVariants --- ### cva 學習指南 由於篇幅設計這裡只能簡單介紹, cva 本質是針對複雜元件的方案。 詳細資訊不如聽聽創作者怎麼說 🎞️[CVA 創造者](https://www.youtube.com/watch?v=B6FrDu2Qbt0&t=158s&ab_channel=FrontendFYI) 👉[CVA Docs](https://cva.style/docs) --- ### cva 效果程式範例 將按鈕元件,再以 cva 提出 intent, size 兩個變因。 ![](https://hackmd.io/_uploads/BkfjI_xR2.png)
{"description":"分享者: Nilson Weng","title":"Charming TailwindCSS","contributors":"[{\"id\":\"ceacb5e9-1b52-45c6-a5db-8c8e3d7a3790\",\"add\":22373,\"del\":9507}]"}
    602 views