CSS

CSS的自定義屬性

字號+ 編輯: 种花家 修訂: 秃顶萧峰 來源: 腾讯QQ兴趣部落 2023-09-12 我要說兩句(0)

你大概已經聽說過 CSS 自定義屬性 (也被稱爲 CSS 變量),可能你是從 Google 發表的這篇文章中得知這個屬性的。你可能尚且不了解這個特性的瀏覽器支持程度,從沒見過相關的最佳實踐,也無從將它同 Less 或者 Sass 做比較,總之就是一頭霧水。那現在就懷揣著一肚子疑問,接著往下看吧,我將爲你一一解答。

兼容性

第一個問題是:CSS 自定義屬性能用在哪?目前從 Can I use 上獲取的信息顯示除了 Edge 外主流瀏覽器的最新版都已經支持這個特性了,而 Edge 也將支持這個屬性。

這說明現在 CSS 自定義屬性已經能用在實際項目中了,相信不久以後開發者們將大大依賴這個特性。但還請在使用之前請先檢查一下本文附錄中 Postcss 對於 CSS 自定義屬性的支持情況,以便做好兼容。

設一個值,任何值都可以

那麽……什麽是自定義屬性呢?簡單來說就是一種開發者可以自主命名和使用的 CSS 屬性。瀏覽器在處理像 color 、 position 這樣的屬性時,需要接收特定的屬性值,而自定義屬性,在開發者賦予它屬性值之前,它是沒有意義的。所以要怎麽給 CSS 自定義屬性賦值呢?這倒和習慣無異:

.foo {
    color: red;
    --theme-color: gray;
}
自定義元素的定義由 -- 開頭,這樣瀏覽器能夠區分自定義屬性和原生屬性,從而將它倆分開處理。假如只是定義了一個自定義元素和它的屬性值,瀏覽器是不會做出反應的。如上面的代碼, .foo 的字體顔色由 color 決定,但 --theme-color 對 .foo 沒有作用。

你可以用 CSS 自定義元素存儲任意有效的 CSS 屬性值:

.foo {
    --theme-color: blue;
    --spacer-width: 8px;
    --favorite-number: 3;
    --greeting: "Hey, what's up?";
    --reusable-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.85);
}

使用

假如自定義屬性只能用於設值,那也太沒用了點。至少,瀏覽器得能獲取到它們的屬性值。

使用 var() 方法就能實現:

.button {
    background-color: var(--theme-color);
}

下面這段代碼中,我們將 .button 的 background-color 屬性值賦值爲 --theme-color 的值。這例子看起來自定義屬性也沒什麽了不起的嘛,但這是一個硬編碼的情況。你有沒有意識到, --theme-color 的屬性值是可以用在任意選擇器和屬性上的呢?這可就厲害了。

.button {
    background-color: var(--theme-color);
}
.title {
    color: var(--theme-color);
}
.image-grid > .image {
    border-color: var(--theme-color);
}

缺省值

如果開發者並沒有定義過 --theme-color 這個變量呢? var() 可以接收第二個參數作爲缺省值:

.button {
    background-color: var(--theme-color, gray);
}
注意:如果你想把另一個自定義屬性作爲缺省值,語法應該是 background-color:var(--theme-color,var(--fallback-color))

傳參數時總是傳入一個缺省值是一個好習慣,特別是在構建 web components 的時候。爲了讓你的頁面在不支持自定義屬性的瀏覽器上正常顯示,別忘了加上兼容代碼:

.button {
    background-color: gray;
    background-color: var(--theme-color, gray);
}

作用域和級聯

要在什麽時候定義這些屬性?在使用之前嗎?自定義屬性遵從標準的作用域和級聯槼則,開發者按照平時使用的習慣來就可以了!

你可能希望將 --theme-color 設置爲全局變量,處處可用。最簡單的方法是使用 :root 偽元素:

:root {
    --theme-color: gray;
}
這樣定義以後,無論是按鈕、標題還是圖片網格乃至整個文档,都可以使用 --theme-color了,

但當你希望不同的模塊使用不同的 --theme-color 值怎麽辦呢?和初始化自定義屬性的步驟相同,只需要在模塊的作用域中給屬性重新賦值,新的顔色就會分模塊生效,而不需要開發者一個個重置使用到 --theme-color 的屬性。

section.about {
    --theme-color: darkblue;
}
section.contacts {
    --theme-color: darkred;
}
section.news {
    --theme-color: teal;
}

當然,你也可以定義複雜的選擇器槼則,應用特定的屬性值:

section.news > .sidenote {
    --theme-color: gray;
}

CSS 計算

calc() 函數常常被用於跨單位的計算:

.child {
    width: calc(100% - 16px);
}
事實上這個計算是在瀏覽器運行時進行的,瀏覽器會將 calc() 的計算結果以像素單位呈現在屏幕上。

calc() 與 CSS 自定義屬性結合以後會很有趣!這一點也是在制定自定義屬性槼範時,經過了深思熟慮才加上的,畢竟這兩者的結合可謂是強強聯手:

:root {
    --base-size: 4px;
}
.title {
    text-size: calc(5 * var(--base-size));
}
.body {
    text-size: calc(3 * var(--base-size));
}

只要最終的結果有意義,開發者無論使用什麽樣的單位都可以:

:root {
    --base-size: 4px;
    --title-multiplier: 5;
    --body-multiplier: 3;
}
.title {
    text-size: calc(var(--title-multiplier) * var(--base-size));
}
.body {
    text-size: calc(var(--body-multiplier) * var(--base-size));
}

CSS 和 JavaScript 間的橋梁

自定義屬性和 Sass、Less 或者 PostCSS 這些處理器語言一個非常重要的不同點在於:瀏覽器是可以解析自定義屬性的。這就意味著開發者可以動態改變自定義屬性的值。這是 CSS 邁出的一大步。

就和平時用 JS 操作元素任意的屬性一般,自定義屬性也可以通過 getPropertyValue 和 setProperty 方法操作 :

const styles = getComputedStyle(document.querySelector('.foo'));
// Read value. Be sure to trim to remove whitespace.
const oldColor = styles.getPropertyValue('--color').trim();
// Write value.
foo.style.setProperty('--color', 'green');

屬性值一旦被改變,所有與這個自定義屬性相關的 CSS 屬性也都會發生改變,倣佛是開發者直接操作了那些 CSS 屬性值似的。這樣就能輕松實現批量修改元素的屬性值。

關於 JS 和 CSS 自定義屬性之間的合作和最佳實踐,大家可以詳細閲讀這篇文章。

附錄:使用預處理器編寫 CSS 自定義屬性

相信你已經迫不及待地想用上這個新技術,但又要考慮兼容尚未實現此特性的瀏覽器,那目前最好的選擇就是使用 PostCSS。

PostCSS 現在可以支持 CSS 自定義屬性的基本功能,也可以防止開發者不斷重複編寫自己的 CSS,但是像和 JS 結合動態改變自定義屬性值,這相對高級的用法暫時還沒有實現方案。

讓我們來看看 PostCSS 能支持的特性和具體表現情況吧:

上表中對比的兩個 Postcss plugin 爲

postcss custom properties: 網頁鏈接

postcss css variables: 網頁鏈接

PostCSS CSS Varibales 中會出現編譯問題的鏈接從上到下分別是:

Caveats: 網頁鏈接

Issue 30: 網頁鏈接

Caveats: 網頁鏈接

若需要用 calc() 則都要和 Postcss Calc 配合使用。
閲完此文,您的感想如何?
  • 有用

    0

  • 沒用

    0

  • 開心

    0

  • 憤怒

    0

  • 可憐

    0

1.如文章侵犯了您的版權,請發郵件通知本站,該文章將在24小時内刪除;
2.本站標注原創的文章,轉發時煩請注明來源;
3.交流群: 2702237 13835667

相關課文
  • 多個高度相同, 屬性inline-block的div,有的div沒有内容而有的div有内容,有内容的會下沉?

  • 讓整個網頁全局變成黑白色調的css代碼

  • CSS生成内容

  • CSS3外輪廓屬性

我要說說
網上賓友點評