使用 CSS 自定義屬性(變數)

jxaa0965發表於2022-08-08
自定義屬性(有時候也被稱作CSS 變數或者級聯變數)是由 CSS 作者定義的,它包含的值可以在整個文件中重複使用。由自定義屬性標記設定值(比如:  --main-color: black;),由var() 函式來獲取值(比如:  color: var(--main-color);
複雜的網站都會有大量的 CSS 程式碼,通常也會有許多重複的值。舉個例子,同樣一個顏色值可能在成千上百個地方被使用到,如果這個值發生了變化,需要全域性搜尋並且一個一個替換(很麻煩哎~)。自定義屬性在某個地方儲存一個值,然後在其他許多地方引用它。另一個好處是語義化的標識。比如, --main-text-color 會比  #00ff00 更易理解,尤其是這個顏色值在其他上下文中也被使用到。
自定義屬性受級聯的約束,並從其父級繼承其值。

基本用法

宣告一個自定義屬性,屬性名需要以兩個減號( --)開始,屬性值則可以是任何有效的 CSS 值。和其他屬性一樣,自定義屬性也是寫在規則集之內的,如下:

element {  --main-bg-color: brown;}
Copy to Clipboard

注意,規則集所指定的選擇器定義了自定義屬性的可見作用域。通常的最佳實踐是定義在根偽類  :root 下,這樣就可以在 HTML 文件的任何地方訪問到它了:

:root {  --main-bg-color: brown;}
Copy to Clipboard

然而這條規則不是絕對的,如果有理由去限制你的自定義屬性,那麼就應該限制。

注意:自定義屬性名是大小寫敏感的, --my-color 和  --My-color 會被認為是兩個不同的自定義屬性。

如前所述,使用一個區域性變數時用  var() 函式包裹以表示一個合法的屬性值:

element {  background-color: var(--main-bg-color);}
Copy to Clipboard

使用自定義屬性的第一步

我們從這個簡單的 CSS 程式碼開始,它將相同的顏色應用在了不同 class 的元素上:

.one {  color: white;  background-color: brown;  margin: 10px;  width: 50px;  height: 50px;  display: inline-block;}.two {  color: white;  background-color: black;  margin: 10px;  width: 150px;  height: 70px;  display: inline-block;}.three {  color: white;  background-color: brown;  margin: 10px;  width: 75px;}.four {  color: white;  background-color: brown;  margin: 10px;  width: 100px;}.five {  background-color: brown;}
Copy to Clipboard

應用在如下 HTML 上:

<div>  <div class="one">1:</div>  <div class="two">2: Text <span class="five">5 - more text</span></div>  <input class="three">  <textarea class="four">4: Lorem Ipsum</textarea></div>
Copy to Clipboard

其呈現是:


注意到在 CSS 程式碼中的重複:背景色  brown 被多處設定。對於一些 CSS 宣告,是可以在級聯關係更高的位置設定,透過 CSS 繼承自然地解決這個重複的問題。但在一般專案中,是不可能透過這樣的方式去解決。透過在  :root 偽類上設定自定義屬性,然後在整個文件需要的地方使用,可以減少這樣的重複性:

:root {  --main-bg-color: brown;}.one {  color: white;  background-color: var(--main-bg-color);  margin: 10px;  width: 50px;  height: 50px;  display: inline-block;}.two {  color: white;  background-color: black;  margin: 10px;  width: 150px;  height: 70px;  display: inline-block;}.three {  color: white;  background-color: var(--main-bg-color);  margin: 10px;  width: 75px;}.four {  color: white;  background-color: var(--main-bg-color);  margin: 10px;  width: 100px;}.five {  background-color: var(--main-bg-color);}
Copy to Clipboard

這裡呈現的結果和前面的例子是一致的,但允許對所需屬性值進行一個規範的宣告。

自定義屬性的繼承性

自定義屬性會繼承。這意味著如果在一個給定的元素上,沒有為這個自定義屬性設定值,在其父元素上的值會被使用。看這一段 HTML:

<div class="one">
  <div class="two">
    <div class="three"></div>
    <div class="four"></div>
  </div>
</div>

配套的 CSS:

.two {
  --test: 10px;
}
.three {
  --test: 2em;
}

在這個情況下,  var(--test) 的結果分別是:

  • 對於元素  class="two" : 10px
  • 對於元素  class="three" : 2em
  • 對於元素  class="four" : 10px (繼承自父屬性)
  • 對於元素  class="one" : 非法值,會變成自定義屬性的預設值

注意,這些是自定義屬性,並不是你在其他程式語言中遇到的實際的變數。這些值僅當需要的時候才會計算,而並不會按其他規則進行儲存。比如,你不能為元素設定一個屬性,然後讓它從兄弟或旁支子孫規則上獲取值。屬性僅用於匹配當前選擇器及其子孫,這和通常的 CSS 是一樣的。

自定義屬性備用值

用  var() 函式可以定義多個備用值(fallback value),當給定值未定義時將會用備用值替換。這對於 Custom Elements 和 Shadow DOM 都很有用。

備用值並不是用於實現瀏覽器相容性的。如果瀏覽器不支援 CSS 自定義屬性,備用值也沒什麼用。它僅對支援 CSS 自定義屬性的瀏覽器提供了一個備份機制,該機制僅當給定值未定義或是無效值的時候生效。

函式的第一個引數是自定義屬性的名稱。如果提供了第二個引數,則表示備用值,當自定義屬性值無效時生效。第二個引數可以巢狀,但是不能繼續平鋪展開下去了,例如:

.two {  color: var(--my-var, red); /* Red if --my-var is not defined */}.three {  background-color: var(--my-var, var(--my-background, pink)); /* pink if --my-var and --my-background are not defined */}.three {  background-color: var(--my-var, --my-background, pink); /* Invalid: "--my-background, pink" */}
Copy to Clipboard

第二個例子展示瞭如何處理一個以上的 fallback。該技術可能會導致效能問題,因為它花了更多的時間在處理這些變數上。

注意:像自定義屬性這些 fallback 語法允許使用逗號。比如  var(--foo, red, blue) 定義了一個  red, blue 的備用值——從第一個逗號到最後的全部內容,都會被作為備用值的一部分。

有效性和值

傳統的 CSS 概念裡,有效性和屬性是繫結的,這對自定義屬性來說並不適用。當自定義屬性值被解析,瀏覽器不知道它們什麼時候會被使用,所以必須認為這些值都是 有效的

不幸的是,即便這些值是有效的,但當透過  var() 函式呼叫時,它在特定上下文環境下也可能不會奏效。屬性和自定義變數會導致無效的 CSS 語句,這引入了一個新的概念: 計算時有效性

無效變數會導致什麼?

當瀏覽器遇到無效的  var() 時,會使用繼承值或初始值代替。

考慮如下程式碼:

HTML

<p>This paragraph is initial black.</p>
Copy to Clipboard

CSS

:root { --text-color: 16px; }p { color: blue; }p { color: var(--text-color); }
Copy to Clipboard

毫不意外,瀏覽器將  --text-color 的值替換給了  var(--text-color),但是  16px 並不是  color 的合法屬性值。代換之後,該屬性不會產生任何作用。瀏覽器會執行如下兩個步驟:

  1. 檢查屬性 color 是否為繼承屬性。是,但是  <p> 沒有任何父元素定義了 color 屬性。轉到下一步。
  2. 將該值設定為它的預設初始值,比如 black。

Result


段落顏色並不是藍色,因為無效代換導致了它被替換成了預設初始值的黑色。如果你直接寫  color: 16px 的話,則會導致語法錯誤,而前面的定義則會生效(段落顯示為藍色)。

注意:當 CSS 屬性 - 值對中存在語法錯誤,該行則會被忽略。然而如果自定義屬性的值無效,它並不會被忽略,從而會導致該值被覆蓋為預設值。

JavaScript 中的值

在 JavaScript 中獲取或者修改 CSS 變數和操作普通 CSS 屬性是一樣的:

// 獲取一個 Dom 節點上的 CSS 變數
element.style.getPropertyValue("--my-var");
// 獲取任意 Dom 節點上的 CSS 變數
getComputedStyle(element).getPropertyValue("--my-var");
// 修改一個 Dom 節點上的 CSS 變數
element.style.setProperty("--my-var", jsVar + 4);


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70019613/viewspace-2909493/,如需轉載,請註明出處,否則將追究法律責任。

相關文章