由自定义属性标记设定值(比如: --main-color: black;
),由 var() 函数来获取值(比如: color: var(--main-color);
)
声明一个自定义属性,属性名需要以两个减号(--
)开始,属性值则可以是任何有效的 CSS 值。和其他属性一样,自定义属性也是写在规则集之内的,如下:
- element {
- --main-bg-color: brown;
- }
通常的最佳实践是定义在根伪类 :root 下,这样就可以在 HTML 文档的任何地方访问到它了:
- :root {
- --main-bg-color: brown;
- }
如前所述,使用一个局部变量时用 var() 函数包裹以表示一个合法的属性值:
- element {
- background-color: var(--main-bg-color);
- }
-
- //用 var() 函数可以定义多个备用值(fallback value),当给定值未定义时将会用备用值替换
- //语法允许使用逗号。比如 var(--foo, red, blue) 定义了一个 red, blue 的备用值——从第一个逗号到最后的全部内容,都会被作为备用值的一部分。
-
- .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" */
- }
备注: 自定义属性名是大小写敏感的,--my-color
和 --My-color
会被认为是两个不同的自定义属性。
继承:自定义属性会继承。这意味着如果在一个给定的元素上,没有为这个自定义属性设置值,在其父元素上的值会被使用。看这一段 HTML:
- <style>
- //配套的 CSS:
- .two {
- --test: 10px;
- }
-
- .three {
- --test: 2em;
- }
- style>
-
- <div class="one">
- <div class="two">
- <div class="three">div>
- <div class="four">div>
- div>
- div>
在这个情况下, var(--test)
的结果分别是:
class="two"
:10px
class="three"
:2em
class="four"
:10px
(继承自父属性)class="one"
:非法值,会变成自定义属性的默认值当浏览器遇到无效的 var()
时,会使用继承值或初始值代替。
考虑如下代码:
<p>This paragraph is initial black.p>
- :root { --text-color: 16px; }
- p { color: blue; }
- p { color: var(--text-color); }
毫不意外,浏览器将 --text-color
的值替换给了 var(--text-color)
,但是 16px
并不是 color 的合法属性值。代换之后,该属性不会产生任何作用。浏览器会执行如下两个步骤:
没有任何父元素定义了 color 属性。转到下一步。段落颜色并不是蓝色,因为无效代换导致了它被替换成了默认初始值的黑色。如果你直接写 color: 16px
的话,则会导致语法错误,而前面的定义则会生效(段落显示为蓝色)。
备注: 当 CSS 属性 - 值对中存在语法错误,该行则会被忽略。然而如果自定义属性的值无效,它并不会被忽略,从而会导致该值被覆盖为默认值。
在 JavaScript 中获取或者修改 CSS 变量和操作普通 CSS 属性是一样的:
- // 获取一个 Dom 节点上的 CSS 变量
- element.style.getPropertyValue("--my-var");
-
- // 获取任意 Dom 节点上的 CSS 变量 window.getComputedStyle
- getComputedStyle(element).getPropertyValue("--my-var");
-
- // 修改一个 Dom 节点上的 CSS 变量
- element.style.setProperty("--my-var", jsVar + 4);
-
-
- //获取root上的css变量
- //:root--指的是根元素html,即document.documentElement
- document.documentElement.style.getPropertyValue('--my-var')
- getComputedStyle(document.documentElement).getPropertyValue("--my-var");
注意:style.getPropertyValue的方式只能获取到内联样式的css变量值,要想获取任意位置的CSS变量要使用getComputedStyle。调用过setProperty后element或html会有内联style,才可以使用style.getPropertyValue获取到
主流浏览器都已支持css变量,但顽强的 ie11仍未支持。
1、css @supports命令(@supports也存在兼容性)
- @supports ((--a: 0)) {
- /** 支持css变量字体为蓝色**/
- .container {
- --my-color: gray;
- background-color: var(--my-color);
- }
- }
-
- @supports (not (--a: 0)) {
- /* 不支持css变量字体为灰色 */
- .container {
- background-color: red;
- }
- }
-
-
- @supports(--css: variables) {
- .container{
- --my-color: blue;
- background-color: var(--my-color, 'blue');
- }
- }
2、js
- const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--masterColor', 'red');
- if (isSupported) {
- /* supported */
- console.log('当前浏览器支持CSS变量')
- } else {
- /* not supported */
- console.log('当前浏览器不支持CSS变量')
- }
使用案例:让一个div滑块向左匀速滑动,正好划出屏幕
- <head>
- <style>
- :root {
- --distance: -100vw;
- }
- * {
- margin: 0;
- padding: 0;
- }
-
- .container {
- position: absolute;
- width: 500px;
- height: 500px;
- margin: 50px;
- }
-
-
- #box {
- width: 20px;
- height: 20px;
- background-color: green;
- margin: 20px 0 0 300px;
- }
- .move {
- animation: moving 3s linear forwards;
- }
-
- @keyframes moving {
- 100% {
- transform: translate3d(var(--distance), 0, 0);
- }
- }
- style>
- head>
- <body>
- <div class="container">
- <button id="move-btn">movebutton>
- <div id="box">div>
- div>
- <script>
- const btn = document.getElementById("move-btn");
- const box = document.getElementById("box");
-
- btn.addEventListener("click", moving);
- function moving() {
- document.documentElement.style.setProperty(
- "--distance",
- "-" + (box.offsetLeft + box.offsetWidth) + "px"
- );
- box.classList.add("move");
- }
- script>
- body>
注意:offsetLeft 是左顶点到最近的定位的父元素的距离,没有定位的父元素就是最初的包含快,正好移动offsetLeft那么就是box左顶点正好贴父元素边框,所以再多移动offsetWidth正好移动出去,向左移为负值。