將CSS變量設置為設計系統的主題可能會有些棘手: 如果它們太顯眼, 系統就會失去一致性。 如果它們太全局化, 你就會失去粒度。
也許我們可以解決這兩個問題。 我想嘗試將設計系統變量歸結為兩種類型: 全局變量和組件變量。 全局變量將使我們在組件間保持一致性。組件變量將給我們帶來粒度和隔離。讓我用一個相當簡單的組件作為例子來告訴你怎麼做。
全局變量
全系統變量是為了保持組件間的一致性而定義的一般概念。
作為一個例子,以一個.alert組件開始,假設我們希望保持頁邊空白和填充的所有空間的一致性。我們可以首先定義全局空間:
然後在我們的組件上使用:
這種做法的主要好處是:
它為分隔符創造了一個單一的真理來源,為作者使用我們的系統定製它提供了一個單一的點。它達到了一致性,因為每個組件都遵循相同的間距。它為設計者和開發者提供了一個共同的參考點。只要設計人員遵循相同的間距限制,代碼的翻譯就是無縫的
但這也帶來了一些問題:
系統通過生成依賴樹來失去模塊性。由於組件依賴於全局變量,因此它們不再是孤立的。它不允許作者在不覆蓋CSS的情況下自定義單個組件。例如,要更改警報的填充而不產生系統範圍的移動,他們必須覆蓋警報組件:
組件範圍變量
組件變量被限定在每個模塊中。如果我們用這些變量生成警報,我們會得到:
主要優點是:
它創建了一個帶有隔離組件的模塊系統。作者可以在不覆蓋組件的情況下精確控制組件,他們只是重新定義變量的值。
沒有辦法保持組件之間的一致性, 也無法按照這種方法進行全系統的更改。讓我們看看我們如何才能獲得兩全其美!
雙層主題系統
該解決方案是一個雙層主題系統,其中全局變量始終通知組件變量。這些層中的每一層遵循一組非常具體的規則。
第一層: 全局變量
具有全局變量的主要原因是為了保持一致性,並且遵守這些規則:
它們以「全局變量」這個詞為前綴,並遵循公式--global--concept--modifier--state--PropertyCamelCase
concept就像一個spacer或main-titlestate類似於hover或expandedmodifier就像sm,或lgPropertyCamelCase類似於BackgroundColor或FontSize
它們是概念,從不與任何元素或組件綁定
這是錯誤的: --global-h1-font-size這是正確的: --global--main-title--FontSize
例如,全局變量設置將如下所示:
第二層:組件變量
第二層的作用域為主題化組件屬性並遵循以下規則:
假設我們在寫BEM,它們遵循這個公式:--block__element--modifier--state--PropertyCamelCase
block__element--modifier選擇器名稱類似於alert__actions或alert--primarystate類似於hover或active如果您不編寫BEM類的名稱,那麼同樣的原則也適用,只需用您的類名替換block__element--modifier組件作用域變量的值總是由全局變量定義。組件變量總是有一個默認值作為回退,以防組件不依賴全局變量。
例如:
您會注意到, 我們正在定義具有全局變量的局部變量。 這是系統工作的關鍵, 因為它允許作者將系統作為一個整體來主題。 例如, 如果他們想要改變所有組件的主色, 他們只需要重新定義--global--primary-color。
另一方面, 每個組件變量都有一個默認值, 因此組件可以獨立存在, 它不依賴於任何東西, 作者可以孤立地使用它。
這種設置允許跨組件的一致性, 它在設計者和開發者之間生成一種共同的語言, 因為我們可以在 Sketch 中設置相同的全局變量作為設計師的緩衝器, 並且它給作者提供了細粒度的控制。
為什麼這個系統工作?
在一個理想的世界裡, 我們作為一個設計系統的創造者, 期望我們系統的"作者"或者用戶在不作任何修改的情況下實現它, 當然, 世界不是理想的, 而且從來沒有發生過。
如果我們允許作者在不需要覆蓋 CSS 的情況下輕鬆地將系統主題化, 那麼我們不僅可以讓他們的生活更簡單, 而且還能減少破壞模塊的風險。 一天結束的時候, 一個可維護的系統就是一個很好的系統。
兩層主題系統生成模塊化和孤立的組件, 作者可以在全局和組件層面對它們進行自定義。 例如:
什麼樣的價值觀應該成為變量?
CSS變量打開代碼的窗口。我們允許作者越多,系統對實現問題就越脆弱。
為了保持一致性, 設置除布局值之外的全局變量; 你不希望作者打破布局。 作為一般規則, 我建議允許訪問您願意提供支持的所有組件。
對於下一個版本的 PatternFly, 一個我正在研究的開源設計系統, 我們將允許定製幾乎所有與布局無關的東西: 顏色、空間、字體處理、陰影等等。
把所有東西放在一起
為了展示這個概念, 我創建了一個 CodePen 項目:
全局變量依賴於_global-variables.scss。它們是保持整個系統一致性的基礎, 並將允許作者進行全局變化。
有兩個組件: 警報和按鈕。 它們是獨立的模塊化實體, 具有範圍變量, 允許作者對組件進行微調。
請記住, 作者將在他們的項目中使用我們的系統作為依賴。 通過讓他們通過 CSS 變量來修改系統的外觀和感覺, 我們正在創建一個可靠的代碼庫, 使系統的創建者更容易維護, 並且更好地使用系統來實現、修改和升級到作者。
例如, 如果作者想:
在整個系統中將原色改為粉紅色;只需在按鈕上將危險顏色更改為橙色;在只有在警告狀態下,填充左側更改為2.3rem
我知道這只是一種方法, 我相信還有其他方法可以成功地在系統上設置變量。 請在評論中告訴我你的想法,我很想聽聽你在做什麼, 並從中學習。