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變數。
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"> <p class="two"> <p class="three"> </p> <p class="four"> </p> <p></p>
定義下面的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
四、響應式
p { --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 */}// Jsif (window.CSS && window.CSS.supports && window.CSS.supports('--a', 0)) { alert('CSS properties are supported');} else { alert('CSS properties are NOT supported');}
總結
相較於傳統的 LESS 、SASS 等前置處理器變數,CSS 變數的優點在於: