- 前言
- 基本用法
- 使用自定義屬性的第一步
- 自定義屬性的繼承
- 自定義屬性的回調(diào)值
- 有效性和值
- 無效的變量會發(fā)生什么
- 通過js中獲取到的css變量值
- var()與rgba()配合實現(xiàn)復用變量
- vue實戰(zhàn): 通過顏色選擇器切換熱力圖主題顏色
前言
自定義屬性(有時可以稱為CSS變量或者層疊variables)是由CSS作者定義的實體从隆,這些實體在一個document內(nèi)可以被重用。一般按照自定義屬性的符號設置(比如,--main-color: black蜓竹;
)然后使用var()函數(shù)使用术羔。(例如color: var(--main-color)
)
復雜的網(wǎng)站有大量的CSS焕窝,通常會有很多重復的值嫉戚。例如刨裆,同一個顏色可能會被在幾百個地方都用到澈圈,可以從全局搜索去一次性替換掉彬檀。自定義屬性允許這個值存儲在一個地方,然后再多個地方引用瞬女。另一個好處是語義標識符號窍帝。(semantic identifier)例如,--main-text-color
比#00ff00
更容易理解诽偷,尤其是這個值在其他的上下文中也存在時坤学。
自定義屬性遵循級聯(lián),會從父級繼承它們的值报慕。
基本用法
定義一個自定義的屬性需要用--開始深浮,然后屬性的值需要是一個有效的CSS值。
和任何其他的屬性一樣眠冈,在一個規(guī)則集中定義:
element {
--main-bg-color: brown;
}
請注意規(guī)則集中的選擇器定義了自定義屬性可以使用的scope飞苇。一個通常的最佳實踐是定義在:root偽類上,從而可以在HTML document全局獲得權限:
:root {
--main-bg-color: brown;
}
不過你也可以在局部scope中使用css變量蜗顽。
注意:css變量的屬性名大小寫敏感布卡,--my-color
會被當作--My-color
屬性。
就像上面提到的雇盖,使用自定義屬性的話忿等,需要在var()函數(shù)中使用。
element {
background-color: var(--main-bg-color);
}
使用自定義屬性的第一步
在不同的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;
}
<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>
注意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);
}
自定義屬性的繼承
自定義屬性會繼承薛匪。這也就意味著如果給定的element沒有屬性值,會繼承父元素的值:
.two {
--test: 10px;
}
.three {
--test: 2em;
}
<div class="one"> <!--invalid-->
<div class="two"><!--10px-->
<div class="three"></div><!--2em-->
<div class="four"></div><!--10px-->
</div>
</div>
不要試圖把它當做一個和其他語言中的變量一樣的東西卷哩,css自定義屬性最終展現(xiàn)形式是computed值蛋辈,所以不要妄想去子樣式中查找到這個變量。自定義屬性僅僅對匹配到的選擇器和它的子元素有效,和普通css一樣冷溶。
自定義屬性的回調(diào)值
使用var()的時候渐白,可以使用回調(diào)函數(shù)。
var()函數(shù)不僅僅可以用于默認的標簽逞频,對于自定義的標簽和Shadow DOM都適用纯衍。
注意:fallback可用于提升兼容性。
規(guī)則可以看下面的例子:
.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" */
}
注意:
- 第二種可能會有性能問題苗胀,因為要不斷地一層一層往下找襟诸。
- 第一個例子中的var(--my-var, red)還可以寫成var(--my-var, red, blue)。
有效性和值
與每個屬性相關的經(jīng)典CSS有效性概念在定制屬性方面不是很有用基协。當解析自定義屬性的值時歌亲,瀏覽器不知道將在何處使用它們,因此必須考慮幾乎所有值都是有效的澜驮。不幸的是陷揪,這些有效值可以通過var()函數(shù)表示法在可能沒有意義的上下文中使用。屬性和自定義變量可能導致無效的CSS語句杂穷,從而導致在計算時間有效的新概念悍缠。
無效的變量會發(fā)生什么
- 檢查是否有父元素可以繼承
- 設置成默認的初始值
比如這個例子:
<p>This paragraph is initial black.</p>
:root { --text-color: 16px; }
p { color: blue; }
p { color: var(--text-color); }
這個例子中的p的color屬性應用了var函數(shù),但是16px是color的無效屬性值耐量。因此找父元素飞蚓,但是沒有父元素,所以這個color的值替換為default initial value廊蜒,替換以后這個屬性就恢復為默認屬性了趴拧。
注意:雖然CSS屬性/值對中的語法錯誤將導致該行被忽略。但是使用級聯(lián)值劲藐、無效替換(使用無效的自定義屬性值)不會被忽略八堡,從而導致該值被繼承。
通過js中獲取到的css變量值
// 從行內(nèi)樣式中中獲取變量
element.style.getPropertyValue("--my-var");
// 從任何地方獲取到變量
getComputedStyle(element).getPropertyValue("--my-var");
// 在行內(nèi)樣式中設置變量
element.style.setProperty("--my-var", jsVar + 4);
var()與rgba()配合實現(xiàn)復用變量
:root {
--my-var: 24, 144, 255;
}
.custom-bg-1 {
background-color: rgba(var(--my-var), 0.5);
}
.custom-bg-2 {
background-color: rgba(var(--my-var), 0.7);
}
vue實戰(zhàn): 通過顏色選擇器切換熱力圖主題顏色
基于iView的ColorPick組件聘芜,實現(xiàn)用戶根據(jù)自己的喜好切換主題色兄渺。
heat.scss
:root {
--heat-cell-bgc: 24, 144, 255;
}
.custom-alpha-8-1 {
background-color: rgba(var(--heat-cell-bgc), 0.125) !important;
}
.custom-alpha-8-2 {
background-color: rgba(var(--heat-cell-bgc), 0.25) !important;
}
...
.custom-alpha-8-8 {
background-color: rgba(var(--heat-cell-bgc), 1) !important;
}
colorFilter.vue
<template>
<div>
<ColorPicker
v-model="cellBackgroundColor"
placement="bottom-start"
@on-change="colorChange"
format="rgb"
/>
</div>
</template>
<script>
const getRGB = (str) => {
const match = str.match(/rgba?\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)?(?:, ?(\d(?:\.\d?))\))?/);
return match
? {
red: match[1],
green: match[2],
blue: match[3],
}
: {};
};
export default {
name: 'color-filter',
data() {
return {
cellBackgroundColor: 'rgb(24, 144, 255)',
};
},
methods: {
colorChange(color) {
// 抽離出rgb值
const { red, green, blue } = getRGB(color);
const rgb = `${red},${green},${blue}`;
// 找到root元素
const rootElement = document.documentElement;
// 更新背景色css變量
rootElement.style.setProperty('--heat-cell-bgc', rgb);
},
},
};
</script>
<style lang="scss" scoped>
</style>
參考鏈接: