CSS变量及其与JS交互

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>
原文地址:https://www.cnblogs.com/guanghe/p/14072769.html