CSS變量
CSS變量,即CSS variable。官方的名稱是級聯變量的CSS自定義屬性,即CSS custom properties for cascading variables。類似於sass,less等預處理器的變量。css變量同樣具備聲明,引用,以及作用域等變量特性。CSS 引入了一種層級變量的概念,從而能夠從容應對可維護性的挑戰。這就會使得在整個 CSS tree 中都可以象征性的引用一個變量。
CSS變量有着天然優勢。不同於預處理器,必須最終編譯成普通的css代碼,CSS變量可以被瀏覽器識別解析,甚至可以用javascript訪問或重新賦值。比如,在線修改一個網站主題色,只需修改相應變量即可實現。某種意義上,這為css開啟了一扇通向各種可能性的大門。可以自定義變量名稱,使變量更有語義,更有可讀性。畢竟primary-color比#0055aa更容易理解,特別是同樣的顏色出現在不同的文件中的時候,顏色之間的關聯關系更加直觀。
CSS變量也叫CSS自定義屬。即為屬性,同樣是由合法的標識和合法的值組成。不同於普通屬性,自定義屬性有"--"前綴,早期的標准也有采用"var-"作為前綴。之所以會采用"--",是因為通常變量聲明常用的前綴"$"或者"@"已經被預處理器sass和Less占用了。為了保證css變量和預處理器變量不產生沖突,所以采用了"--"。
1 /*聲明變量*/
2 :root{
3 --primary-color: green;
4 }
5 /*引用變量*/
6 .primary-button{
7 background: var(--primary-color) 8 }
var函數可以設置一個默認值,如果變量不存在直接使用默認值
1 /*定義了--color背景為綠色,否則使用默認值紅色*/
2 :root {
3 --themeColor:green;
4 }
5 body {
6 background-color:var(--themeColor, red);
7 }
變量聲明中,屬性值不能直接進行數學運算,需要借助calc()函數,如果是字符串,則可直接拼接。
1 /*正確,數字可計算拼接*/
2 body {
3 --fontSize: 20;
4 margin-top: calc(var(--fontSize) * 1px);
5 }
6 /*正確,字符創可直接拼接*/
7 body {
8 --backgroundColor: green;
9 background: var(--backgroundColor, red) url(../../images/background.jpg) no-repeat fixed top;
10 }
11 /*錯誤,數字不可直接拼接*/
12 .box {
13 --size-one:14;
14 font-size:var(--size-one)px;
15 }
CSS變量可以用在任意css選擇器中,甚至可以用在style以及@media中。讀取的時候,優先級最高的聲明生效,子元素的變量值會覆蓋父元素的值,這與 CSS 的"層疊"(cascade)規則是一致的。
1 /*發生覆蓋,最終為紅色*/
2 :root {
3 --color: green;
4 }
5 body {
6 --color: red;
7 }
變量值可以是有效的css屬性值,比如顏色,尺寸,定位,角度,字符串,數字等,也可以是多個字段的組合,甚至可以是javascript語句
1 :root{
2 --main-color: #4d4e53;
3 --main-bg: rgb(255, 255, 255);
4 --logo-border-color: rebeccapurple;
5 --header-height: 68px;
6 --content-padding: 10px 20px;
7 --base-line-height: 1.428571429;
8 --transition-duration: .35s;
9 --external-link: "external link";
10 --margin-top: calc(2vh + 20px);
11 --foo: if(x > 5) this.width = 10;
12 }
JS交互
CSS 里面定義的JS代碼,對於CSS來說是無效值,但是可以被 JavaScript 讀取。這意味着,CSS 變量提供了 JavaScript 與 CSS 通信的一種途徑。
javaScript檢測瀏覽器是否支持 CSS 變量
1 const isSupported =
2 window.CSS &&
3 window.CSS.supports &&
4 window.CSS.supports('--a', 0); 5
6 if (isSupported) { 7 /* supported */
8 } else { 9 /* not supported */
10 }
JS讀取CSS變量
1 root.style.getPropertyValue('--color').trim();
但這種使用原生element的方式讀取css屬性的方法,僅僅讀取root.style中聲明的變量,並不能讀取:root選擇器中聲明的變量,讀取選擇器中的變量,需要借助styleSheet或者getComputedStyle。
1 //獲取變量
2 const root = document.documentElement; 3 let root_computed = getComputedStyle(root); 4 root_computed.getPropertyValue('--color').trim(); 5 //設置變量
6 root.style.setProperty('--color','green'); 7 //刪除變量
8 root.style.removeProperty('--color');
針對更換主題的需求,我們可以這樣
1 <style>
2 :root.global__style--primary {
3 --button-color: green;
4 --button-font-size:14px;
5 --button-text-color: #fffff;
6 }
7 :root.global__style--warning {
8 --button-color:orange;
9 --button-font-size:12px;
10 --button-text-color:#fffff;
11 }
12 .button {
13 background-color:var(--button-color);
14 font-size:var(--button-font-size);
15 color:var(--button-text-color);
16 }
17 </style>
18 <script>
19 //通過操作root的className,更新變量
20 let root = document.documentElement; 21 root.className = 'global__style--primary'
22 // or
23 root.className = 'global__style--warning'
24 </script>
監聽事件:實現的簡單鼠標跟隨
1 <html>
2 <head>
3 <style>
4 .mover {
5 width: 50px;
6 height: 50px;
7 background: red;
8 position: absolute;
9 left: var(--mouse-x);
10 top: var(--mouse-y);
11 }
12 </style>
13 <script>
14 let root = document.documentElement; 15 root.addEventListener("mousemove", e => { 16 root.style.setProperty('--mouse-x', e.clientX + "px"); 17 root.style.setProperty('--mouse-y', e.clientY + "px"); 18 }); 19 </script>
20 </head>
21 <body>
22 <div class="mover"></div>
23 </body>
24 </html>