CSS變數能幫助我們幹什麼
在一些指令式程式設計語言中,像Java、C++亦或是JavaScript,通過變數我們能夠跟蹤某些狀態。變數是一種符號,關聯著一個特定的值,變數的值能隨著時間的推移而改變。
在像CSS這種宣告式語言中,隨著時間而改變的值並不存在,也就沒有所謂變數的概念了。
CSS 引入了一種層級變數的概念,從而能夠從容應對可維護性的挑戰。這就會使得在整個 CSS tree 中都可以象徵性的引用一個變數
一、什麼是CSS變數
CSS 變數當前有兩種形式:
變數,就是擁有合法識別符號和合法的值。可以被使用在任意的地方。可以使用var()函式使用變數。例如:var(–example-variable)會返回–example-variable所對應的值
自定義屬性。這些屬性使用–where的特殊格式作為名字。例如–example-variable: 20px;即使一個css宣告語句。意思是將20px賦值給–example-varibale變數
二、變數的宣告
變數的命名
變數宣告使用兩根連詞線–表示變數,$color是屬於Sass的語法,@color是屬於Less的語法,為避免衝突css原生變數使用–)
注意: 變數名大小寫敏感,--header-color
和--Header-Color
是兩個不同變數
宣告方式
CSS變數宣告的方式非常簡單,如下,宣告瞭一個名叫color的CSS變數。
- 在css檔案中寫
- 寫在html標籤的inline-style裡
- 用JS給某個元素宣告,方法.style.setProperty
body{
--color: red;
}
<body style="--color: red;"></body>
document.getElementsByTagName(`body`)[0].style.setProperty(`--color`, `red`)
變數值的型別
如果變數值是一個字串,可以與其他字串拼接
--bar: `hello`;
--foo: var(--bar)` world`;
body:after {
content: `--screen-category : `var(--screen-category);
}
如果變數值是數值,不能與數值單位直接連用,必須使用calc()函式,將它們連線
.foo {
--gap: 20;
/* 無效 */
margin-top: var(--gap)px;
}
.foo {
--gap: 20;
margin-top: calc(var(--gap) * 1px);
}
如果變數值帶有單位,就不能寫成字串
/* 無效 */
.foo {
--foo: `20px`;
font-size: var(--foo);
}
/* 有效 */
.foo {
--foo: 20px;
font-size: var(--foo);
注意: 變數值只能用作屬性值,不能用作屬性名
.foo {
--side: margin-top;
/* 無效 */
var(--side): 20px;
}
上面程式碼中,變數–side用作屬性名,這是無效的
三、CSS變數的繼承&作用域
自定義屬性同樣支援繼承。一個元素上沒有定義自定義屬性,該自定義屬性的值會繼承其父元素
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” 對應的節點: element: 2em
- class=”four” 對應的節點: 10px (inherited from its parent)
- class=”one” 對應的節點: 無效值, 即此屬性值為未被自定義css變數覆蓋的預設值
最頂層的作用域就是:root
四、響應式
div {
--color: #7F583F;
--bg: #F7EFD2;
}
.mediabox {
color: var(--color);
background: var(--bg);
}
@media screen and (min-width: 768px) {
body {
--color: #F7EFD2;
--bg: #7F583F;
}
}
五、與前處理器的不同
1、前處理器變數不是實時的
$color:#7F583F;
@media screen and (min-width: 768px) {
$color: #F7EFD2;
}
.mediabox {
background: $color;
}
編譯結果
.mediabox {
background: #7F583F;
}
2、前處理器不能限定作用域
$zcolor:blue;
.ulbox {
$zcolor:red;
}
ul{
color: $zcolor;
}
編譯為
ul {
color: blue;
}
3、前處理器變數不可互操作
原生的CSS自定義屬性可以與任何CSS前處理器或純CSS檔案一起使用
六、JS操作變數
CSS 變數可以和 JS 互相互動
:root{
--testMargin:70px;
}
// 讀取
var root = getComputedStyle(document.documentElement);
var cssVariable1 = root.getPropertyValue(`--testMargin`).trim();
console.log(cssVariable1); // `70px`
// 寫入
document.documentElement.style.setProperty(`--testMargin`, `100px`);
var cssVariable2 = root.getPropertyValue(`--testMargin`).trim();
console.log(cssVariable2); // `100px`
// 刪除
document.documentElement.style.removeProperty(`--testMargin`);
var cssVariable3 = root.getPropertyValue(`--testMargin`).trim();
console.log(cssVariable3); // `70px`
七、相容性
檢測瀏覽器是否支援CSS自定義屬性的方法
/*css*/
@supports ( (--a: 0)) {
/* supported */
}
@supports ( not (--a: 0)) {
/* not supported */
}
// Js
if (window.CSS && window.CSS.supports && window.CSS.supports(`--a`, 0)) {
alert(`CSS properties are supported`);
} else {
alert(`CSS properties are NOT supported`);
}
https://caniuse.com/#search=c…
總結
相較於傳統的 LESS 、SASS 等前處理器變數,CSS 變數的優點在於:
- CSS 變數的動態性,能在頁面執行時更改,而傳統前處理器變數編譯後無法更改
- CSS 變數能夠繼承,能夠組合使用,具有作用域
- 配合 Javascript 使用,可以方便的從 JS 中讀/寫
參考