# 在調適 Bootstrap 和 Tailwind 共用上的困境 ### 研究目標 > 做到美術提供的 css、html 直接可以複製貼上使用。 > 考慮後續的維護與可客製化的彈性,必須使用 Tailwind。 #### 困難一、Reset 樣式不同 - Bootstrap 自身的 reset 樣式 (以下擷取自 bootstrap 原始碼 .scss 片段) ![image](https://hackmd.io/_uploads/Sk_K_ksNA.png) - 美術這邊又重複定義了 Reset 樣式 ? (不太確定此作用的目的) 取自 http://meyerweb.com/eric/tools/css/reset/ ![image](https://hackmd.io/_uploads/BklftJiEC.png) - Tailwind 的 Reset 樣式是採用 Preflight https://tailwindcss.com/docs/preflight #### 困難二、Bootstrap 的排他性很強 - Bootstrap 沒有預留,或是避免與其他UI樣式庫衝突的機制。 對比,Tailwind 而言,可以通過設置 prefix 方式來避免衝突。 ![image](https://hackmd.io/_uploads/ByolckiEA.png) - 經過測試後,發現即使 Tailwind 設置了前綴 tw- 來避免衝突外,還要將 base、utilities 關閉,這意味著,幾乎整個 Tailwind 的功能全數關閉下,才能讓 Bootstrap 正常運作。☹️ ```css @tailwind base; // 移除 @tailwind components; @tailwind utilities; // 移除 ``` ### 為何如此 ? 因為 Bootstrap 諸多設計想法跟 tailwind 可以說是非常相似。 Tailwind 的作者就曾說過,自己是 Bootstrap、Sass 的愛好者,但因為工作中遭遇諸多困境後,才鑑界並創造出 Tailwind,自然很多想法是相似的。舉例來說,bootstrap 和 tailwind 兩邊都有 container 這樣的類名,但是運作與底層 css 的實現手法差異很大。 ```css /* bootstrap */ .container, .container-fluid, .container-xxl, .container-xl, .container-lg, .container-md, .container-sm { --bs-gutter-x: 1.5rem; --bs-gutter-y: 0; width: 100%; padding-right: calc(var(--bs-gutter-x) * 0.5); padding-left: calc(var(--bs-gutter-x) * 0.5); margin-right: auto; margin-left: auto; } /* tailwind */ .container { width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } @media (min-width: 1536px) { .container { max-width: 1536px; } } ``` - 我也反過來嘗試,去讓 boostrap 能帶有像是 "bs-" 的前綴來避免衝突,我去官方的 github 把源碼 git-clone 下來,並且去重新編譯出新版本,以此隔離樣式的作用範圍,讓他能與 tailwind 一起使用。 - ![image](https://hackmd.io/_uploads/HyS0nksV0.png) 但是 bootstrap 除了自身的樣式外,他還包括由 js 控制的 UI效果。換句話說,你除了要重新編譯樣式表 css 文件,還要重新編譯他的 js 檔案。 - ![image](https://hackmd.io/_uploads/BJbE6kjVC.png) ### 然而,這就是更加困難的地方 舉例來說,這是 bootstrap 賦予 navbar、dropdown 元件UI效果的 js 程式,過程使用大量的 selector 的語法對元件直接設置樣式屬性來實現 UI 效果。也正因為如此,在使用上,他需要你提供他 select 的識別名稱 (像是 id、class) - ![image](https://hackmd.io/_uploads/BkNu1ljNC.png) 像是這裡就是透過 data-bs-target 這個屬性,讓動畫效果可以作用於該目標。 而這裡的 collapse (類似 tailwind hidden),透過 toggle (切換)來實現效果。 - ![image](https://hackmd.io/_uploads/H1VAJxjN0.png) 基於這樣的方式,讓 Boostrap 需要定義大量與類名,高度相關的識別名、事件名,來加以控制。 - ![image](https://hackmd.io/_uploads/Skt3TJo4A.png) 而這就是 js 最難修正定義的部分,因為太多了... 🥲 (js 部分 4000 多行而已) 增加樣式類名前綴還可以使用 postcss 去自動化處理 (css 部分有 11835 行) 修正 js 的部分肯定要靠"工人智慧" 😂 更別說修正後難以一一檢驗,有錯誤與異常的風險。 <br> ## 結論 對於開發UI介面上,考慮到後續的維護性、開發彈性、開發效率,Tailwind 是被諸多企業實證過的優秀選項。再加上我們的團隊中,較多是對 Tailwind 熟悉,具有商業實戰經驗的開發者,至於 Bootstrap 方面,主要是因為他容易上手,對美術這邊的較友善,能用他來完成初步版面設計。此外,原本目標是,進而減少我們這邊的工作量。 但就現況而言,美術完成後交付給我們的文件,我們無法直接使用,加上有元件化的需求,重寫成 Tailwind 是必然結果。 也請大家思考一下,考慮日後轉換上,如美術的美術效果依賴 Bs 提供的方便好用的元件功能,僅會增加我們重現的成本。是否我們現在就要提出建議,採取一些措施,讓我們的開發風險可以減少。