使用CSS變量進行主題化:全局變量和局部變量

2021-01-11 webstack前端棧

將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

我知道這只是一種方法, 我相信還有其他方法可以成功地在系統上設置變量。 請在評論中告訴我你的想法,我很想聽聽你在做什麼, 並從中學習。

相關焦點

  • JS代碼中如何使用局部變量和全局變量
    JS開發人員在編寫代碼時可能犯的最大錯誤之一就是聲明不必要的全局變量。全局變量對程式設計師非常有幫助,但如果不謹慎使用它們,它們會影響任何瀏覽器的速度和效率。簡短說明全局變量和局部變量JS中主要使用兩種類型的變量:局部變量和全局變量。
  • C語言局部變量和全局變量的區別
    2,使用全局變量程序運行時速度更快一些(因為內存不需要再分配),同樣現在也快不了多少。 3,對於局部變量的名字空間汙染,這個在不使用太多變量時是可以避免的。
  • 一文讀懂Python中的全局變量局部變量和作用域
    通常小白在寫代碼時,只知道引用變量來應對一些基礎的編碼問題,當面試官問及局部變量和全局變量的具體細節時,就會一臉懵逼,傻傻分不清楚!其實想要徹底了解局部變量和全局變量的關係,本質是大家需要明白何為作用域!這篇文章會帶大家徹底搞懂這三者之的唇齒相依的關聯!Python中,程序的變量並不是在哪個位置都可以訪問的,訪問權限決定於這個變量是在哪裡賦值的。
  • 全局變量和成員變量的區別分析
    變量分為局部與全局,局部變量又可稱之為內部變量。由某對象或某個函數所創建的變量通常都是局部變量,只能被內部引用,而無法被其它對象或函數引用。   全局變量既可以是某對象函數創建,也可以是在本程序任何地方創建。全局變量是可以被本程序所有對象或函數引用。一個局部變量在被其它對象引用時,會是一個空值。但全局變量卻不會出現這種情況。
  • C語言二級必備知識,全局變量和局部變量,一看就會的C語言知識。
    局部變量定義變量一般有三種形式:在函數的開頭定義在函數的外部定義在複合語句中定義其中在函數的開頭和在複合語句中定義的時候,只能在函數內部和該複合語句中使用,像這種變量稱為局部變量。全局變量:我們知道程序的編譯單位是源程序文件,而一個源程序可以包含若干個函數。在函數內部定義的變量稱為局部變量,在函數外部定義的變量成為全局變量,也叫全程比變量。 全局變量可以為其他函數所使用,他的作用域是從定義到源文件的的結束。
  • 使用vue-cli3創建的項目如何引入less全局變量
    前言:本demo是基於腳手架3創建的vue項目,主要演示的是如何使用vw實現移動端適配;並且在項目中如何引入自定義的less全局變量。一.實現在vue項目中使用less全局樣式變量1.安裝 less less-loader做完上邊的vw適配,下邊開始配置使用less,其實在使用腳手架3創建項目時,是可以選擇css預處理器類型的,我這裡手動安裝點快了,沒有選擇安裝css預處理器,所以需要自己安裝less依賴包:
  • Sass簡易指南之基本語法詳析:變量大作戰
    直到最近,規則集和其他範圍內聲明變量的作用域才默認為本地。如果已經存在同名的全局變量,從 3.4 版本開始,Sass 已經可以正確處理作用域的概念,並通過創建一個新的局部變量來代替。全局變量與局部變量先來看一下代碼例子://SCSS$color: orange !
  • Sass簡易指南之基本語法詳析:變量大作戰
    直到最近,規則集和其他範圍內聲明變量的作用域才默認為本地。如果已經存在同名的全局變量,從 3.4 版本開始,Sass 已經可以正確處理作用域的概念,並通過創建一個新的局部變量來代替。全局變量與局部變量先來看一下代碼例子://SCSS$color: orange !
  • for循環中的局部變量引起的問題
    可以看到,這裡的 x 是一個在for循環的局部變量,按照正常的理解,在for循環外面調用 x 應該是報錯的,但是在Python中,for循環裡面聲明的變量,在for循環結束後,會保留 x 的值。第二種情況那如果我們直接聲明一個全局變量呢,最後輸出的會是最開始的值嗎?
  • Python定義全局變量的用法
    全局變量是程式語言中常見的一種變量。全局定義,可以是某對象函數創建,也可以是程序任何位置創建,能夠被程序中的所有對象或函數進行引用。全局變量的定義有利於程序的變量共享,簡化了添加和修改的編程代碼。和C語言一樣,Python也具有全局變量,其定義全局變量的用法有兩種:
  • C語言中,全局變量濫用的後果竟如此嚴重?
    變量分為局部與全局,局部變量又可稱之為內部變量。由某對象或某個函數所創建的變量通常都是局部變量,只能被內部引用,而無法被其它對象或函數引用。全局變量既可以是某對象函數創建,也可以是在本程序任何地方創建。全局變量是可以被本程序所有對象或函數引用。
  • 線程安全:局部靜態變量的初始化
    一個簡單的例子關於代碼塊中的靜態變量(相對於全局範圍中的靜態變量)的一個原則是:當代碼執行流第一次運行到靜態變量的聲明處時才會進行初始化,且僅此一次。下面的代碼,會存在潛在的競爭條件:上面代碼的本意是:只在第一次函數被調用的時候,才進行耗時久的計算,下一次則直接返回一個緩存值。問題在於,這段代碼不是線程安全的。
  • Vue新特性:在CSS中使用JS變量
    那麼怎麼才能在CSS中使用JS變量呢?那就只能用JS操作DOM然後把變量塞進style裡了,比如用ref獲取到DOM元素,然後dom.style.color = this.color。於是CSS也引入了變量的這個概念,自從有了CSS變量,很多事情真的方便了許多,通過JS操作CSS變量,然後再在需要的地方使用CSS變量,這種方法比之前的高效得多。
  • Axure中全局變量的應用技巧
    編輯導讀:在實際應用中,全局變量起到了信息傳遞作用和標誌作用,可以在多個頁面間傳遞信息,或者作為特殊場景的判斷依據。本文作者對Axure中全局變量的應用進行了介紹,適合對Axure的頁面、元件、交互事件等有基本了解的讀者。
  • React-Native使用全局變量踩坑記
    加上注釋是為了防止剛接觸這塊代碼的人看到這個導入,沒有地方使用,而誤以為是沒有用處的代碼,順手把它刪除。搞完之後我們就可以「肆意妄為」了,在代碼中有用到屏幕寬高的地方我們都可以直接使用width和height變量來作為屏幕的寬高,再也不需要先導入再get才能拿到屏幕的寬高值。
  • React-Native使用全局變量踩坑記
    屏幕寬高是個固定值我們完全可以在初始化的時候獲取,然後存起來,之後賦值給一個全局變量。既然是全局變量,那全世界人民都能用到它,想在哪裡用就在哪裡用,媽媽再也不用擔心我天天get去拿值。有了思路直接開幹!
  • C語言中的變量詳解
    C中的變量,按作用域可分為兩種,局部變量和全局變量。局部變量:也稱內部變量。局部變量是在函數內做定義說明的,其作用域僅限於函數內部,離開函數後再使用這種變量是非法的。在函數中使用全局變量,一般要作全局變量說明。只有在函數內經過說明的全局變量才能使用。全局變量的說明符extern。但在一個函數之前定義的全局變量,在該函數內使用可不再加以說明。
  • web前端開發 CSS/CSS3原生變量你真的了解嗎?
    為什麼需要變量呢?在所有的程序語言中,變量的設置都是最開始的學習內容,那為什麼各種程序都需要變量呢?變量的最大的好處就是可以降低代碼的大小,通過在內容空間中存儲一個變量就可以在之後的程序中多次使用該變量,甚至可以通過簡單的計算得到多個值。
  • php變量是什麼?php變量的數據類型、命名規則等詳細介紹
    php變量雖然很簡單,大家都會使用,但是很多人並沒有真正的了解php變量。今天小編講php變量專題,就是希望能幫助大家更徹底的了解php變量,在使用中更得心應手。下邊對php變量的介紹來源於小編的理解和學習筆記整理所得,如有不對的地方,望批評指出,謝謝!二、php變量1、什麼是php變量?
  • C語言全局變量存放在哪裡?
    全局變量的作用域是從全局變量定義的位置到本源文件結束都有效。我們先看一下全局變量在反彙編中是怎麼體現的,如示例示例代碼CH07_3_4。6: int j = i;00401028 mov eax,[i (00421a30)]這一行中(00421a30)正是全局變量i的存放地址。全局變量編譯的時候就已經確定了內存地址和寬度,變量名就是內存地址的別名。如果不重新編譯(也就是不重新構建程序),全局變量的內存地址將不會改變。