We need a better UI component library - Styled System
Side
上方簡報是我今年在 Modern Web 2019 分享的主題,將部份重點整理成此篇文章。
前言
不知道大家有沒有發現,在元件化的時代,無論你是使用 React/Vue.js/Angular,在不同專案裡可能一直重複做同樣功能的元件,只有樣式需要被改變,例如 Button、Checkbox、Radio button、Modal、Carousel 等,我們觀察到大部分元件的行為是一致的,是否能夠彈性的變更樣式?要如何讓我們開發專案更有效率?
隨著時代的演進,各種 UI library 一定會有好與不好的地方,我們來回顧過往的 CSS 技術,希望可以從中學習各自的優良部份。
UI library 的迭代演化與優缺點
CSS Framework / UI Library
觀察早期的 CSS framework(例如:Bootstrap、Pure.css)可以直接在 mockup 加上 class 名稱,修改樣式和改變 DOM 結構是非常直覺的,但是缺少元件化,無法快速完成功能。
UI Component Library
元件化的 UI Library(例如:Material-UI、Ant Design)可以快速完成功能,但是在使用元件時,並不知道元件有哪些 DOM? 這些 DOM 對應的 class 名稱是什麼? 必須找到對應的 class 名稱,再覆蓋樣式,修改樣式會變得很麻煩。
使用現成的 Library,可以快速開發,但是無法因應特殊需求,反而提高專案維護的困難度,所以客製化元件成為許多企業選擇的解決方案。
透過 React
搭配 styled-components
,整理幾個基本範例 (可參考 簡報內的範例 )。
將客製化元件時所遇到的問題整理如下:
客製化元件所遭遇的困難
props 命名
使用元件時,傳遞 props 名稱不一致,容易造成開發者的困惑。
客製化樣式需傳入對應的 props,程式碼很繁冗
假如需要開發樣式非常彈性的元件,搭配 styled-components 寫 function 傳入 props 去設定特定樣式,會寫很多重複的程式碼。
不同狀態顯示不同樣式時,程式碼需要封裝
如果我們必須根據不同狀態顯示不同樣式,為了讓程式碼更簡潔,可能需要寫一個 higher order function,傳入樣式的 object 和當前的狀態,使用元件時,再透過這個 function 定義樣式。
當元件的樣式更複雜時,例如按鈕有不同特定樣式(Default/Primary/Danger)和尺寸(Default/Small/Large),你可以試著思考看看,寫起來是否會變得非常麻煩?
RWD 元件開發複雜
你可能需要寫下面這樣的程式碼,根據不同設備重新再寫一次樣式做修改。
const Article = styled.div`
width: 100%;
…
@media (min-width: 567px) {
width: 50%;
…
}
@media (min-width: 768px) {
width: 25%;
…
}
`;
綜合以上 UI Library 的優缺點:
- CSS Framework / UI Library => 缺乏元件化
- UI Component Library => 較難客製化樣式
- 客製化元件 => 開發過程會遇到一些問題
所以我們希望有一套 UI component Library 可以同時具有元件化的方便性,又能夠達成客製化的需求,幫助我們建立更有彈性的元件。
Styled System 介紹
styled-system 是開源專案,2017 Release 第 1 版,到 2018 的 第 2 版 比較穩定,2019 6 月出 第 5 版,作者 Brent Jackson 同時也是 GatsbyJS 的貢獻者。
將簡報提到的基本案例,重新透過 Styled System 改寫 之後,可以發現:
- 大幅降低 props 命名或格式不一致的問題
- 更好的抽象化樣式,程式碼變得更少
- 根據不同狀態,更彈性的修改對應樣式
- 靈活的處理 RWD 樣式
- 透過 theme 快速變更主題樣式
我們可以直接在元件上定義排版/字級/顏色/RWD 等樣式,例如:
<Box m={2} />
<Box p={[2, 3]} />
<Box fontSize={[1, 2]} />
<Box color="primary" />
透過 Styled System,使用元件時,能夠直接設定樣式,變得非常直覺,但同時又能享受元件的語意化以及封裝好的樣式,程式碼更簡潔、組合更彈性、使用更方便,還能夠達成客製化的需求。
使用 Styled System 開發專案的心得
因為公司專案是在今年年初時導入 Styled System 開發,目前正和同仁們努力將我們做好的 UI Library 應用在不同的專案中,心得應該會越來越多,最後決定另外再寫一篇 Q&A,可能會不定期更新喔~
延伸閱讀
- https://jxnblk.com/
- https://github.com/styled-system/styled-system/blob/master/CHANGELOG.md
- https://styled-system.com/guides/migrating/
- https://github.com/styled-system/styled-system/releases/tag/v2.0.0
- https://github.com/styled-system/styled-system/releases/tag/v5.0.0
- https://en.wikipedia.org/wiki/Law_of_the_instrument#Abraham_Maslow
最後跟大家分享『錘子理論』,如果你手裡只有一把錘子,那你看什麼東西都像釘子。
Maslow's hammer - if all you have is a hammer, everything looks like a nail
如果你只有一把錘子,你只能夠釘東西,只有一種執行方法,但我們希望不只是解決問題,我們應該去衡量新工具能夠帶來的優缺點,讓自己擁有更多可行方案。 經過技術的迭代,光是 CSS 的架構方法就有像是 OOCSS/BEM/CSS Modules/Styled Components 等,都是希望能夠改善命名、優化效能、提高程式碼易讀性、增加重用程度等等、讓程式碼做更好的抽象化。 不要對熟悉的工具有過度的依賴,當然也不要為了追求新技術而去使用,大家可以思考 Styled System 是不是真的適合應用在目前的專案裡? 或許 Styled System 不是你現在的靈藥,但是希望未來會是你其中一個很棒的選擇 🤠
- Styled System
- Styled Component
- Modern Web