CSS 自定义属性(变量)

var

var() 函数用来获取和使用 CSS 变量 (CSS Variables

1
var( <custom-property-name> [, <declaration-value> ]? )
  • custom-property-name

    自定义属性名,如以 ‘–’ 开头的自定义属性,--default-width

  • declaration-value

    声明值(候选值),如果自定义属性值无效时,则使用该值替换

    不能指定多个候选值,如:var(--color, red, blue),但可以通过嵌套函数实现,var(--color, var(--default-color, blue))

@apply

语法

1
2
3
4
5
6
7
8
:root {
--custom-property-name: {
prop-name: value;
/*...*/
}
}

@apply --custom-property-name;

用途

  • clearfix

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    :root {
    --clearfix: {
    display: table;
    clear: both;
    content: '';
    };
    }

    div:after{
    @apply --clearfix;
    }
  • overflow-ellipsis

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    :root {
    --mixin-overflow-ellipsis: {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    };
    }

    .overflow-box {
    @apply --mixin-overflow-ellipsis;
    }
  • 三角形

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    :root {
    --zero-size: {
    width: 0;
    height: 0;
    };

    --triangle-to-bottom-size: 50px;
    --triangle-to-bottom-color: #007bff;

    --triangle-to-bottom: {
    @apply --zero-size;
    border-style: solid;
    border-width: var(--triangle-to-bottom-size) var(--triangle-to-bottom-size) 0 var(--triangle-to-bottom-size);
    border-color: var(--triangle-to-bottom-color) transparent transparent transparent;
    };
    }

    .triangle-to-bottom {
    @apply --triangle-to-bottom;
    }

兼容性

目前没有浏览器支持,Chrome 之前支持后来又移除

参考

CSS 变量

通过下面的方式来声明变量:

1
--variable-name: variable-value;

变量名区分大小写,变量值可以是颜色、字符串、多个值的组合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
:root {
--main-color: #03a9f4;
--main-bg: rgb(255, 255, 255);
--logo-border-color: blue;

--header-height: 68px;
--content-padding: 10px 20px;
--base-line-height: 1.428571429;
--transition-duration: .35s;

--external-link: "external link";
--margin-top: calc(2vh + 20px);

--toolbar-theme: {
background-color: hsl(120, 70%, 95%);
border-radius: 4px;
border: 1px solid var(--theme-color late);
};
}
  • 全局变量

    使用 :root 作用域来定义全局变量

    1
    2
    3
    :root {
    --global-color: #03a9f4;
    }
  • 局部变量

    在特定的元素、类下定义变量

    1
    2
    3
    4
    .hover {
    --color: #03a9f4;
    color: var(--color);
    }
  • 变量组合

    1
    2
    3
    4
    .block {
    --text: 'Hello';
    --content: var(--text)' World';
    }

    新声明变量的值不能由已定义的变量计算而成

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    :root {
    --font-size: 1rem;
    --padding: 10px;
    }

    .font_size_medium {
    // 错误用法
    --medium: var(--font-size)*1.5;
    font-size: var(--medium);

    // 正确用法
    font-size: calc(var(--font-size)*1.5);
    }

    .padding_medium {
    padding: 0 0 calc(var(--padding)*1.5);
    }
  • 变量继承

    1
    2
    3
    4
    5
    6
    7
    8
    9
    :root {
    --border: 1px;
    }

    .border-medium {
    --border: initial;
    --border: 1.5px;
    --border: inherit;
    }

JS 获取变量

在 JS 中可以通过 getPropertyValue()setProperty() 来获取和修改 CSS 变量值。

1
2
3
4
5
6
7
8
9
10
:root {
--color: #03a9f4;
}

// READ
const rootStyles = getComputedStyle(document.documentElement); // :root
const color = rootStyles.getPropertyValue('--screen-category').trim();

// WRITE
document.documentElement.style.setProperty('--color', '#03a9f4');

扩展

  • 使用 CSS 变量时,只要语法正确也能正常解析;但如果变量值不合规,则会使用默认值替换

    1
    2
    3
    4
    5
    body {
    --color: 20px;
    background-color: #369;
    background-color: var(--color, #cd0000); // transparent
    }
  • CSS 变量默认会尾随一个空格,定义数字常量时需使用 calc() 计算

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 错误
    body {
    --size: 20px;
    // 等同于 font-size:20 px 20 与 px 之间有个空格
    font-size: var(--size);
    }

    // 正确
    body {
    --size: 20;
    font-size: calc(var(--size) * 1px);
    }
  • CSS 变量不能作为媒体查询值使用

    1
    @media screen and (min-width: var(--breakpoint) {}
  • CSS 变量不能用于图片地址

    1
    background: url(var(--url)); // 无效

用途

兼容性

除 IE 外,其它浏览器均支持

检测浏览器是否支持 CSS 自定义属性

1
2
3
4
5
6
7
@supports((--c: 0)) {
/* 支持 */
}

@supports(not (--c: 0)) {
/* 不支持 */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
if (CSS && CSS.supports && CSS.supports('--c', 0)) {
/* 支持 */
} else {
/* 不支持 CSS.supports() */

// https://gist.github.com/wesbos/8b9a22adc1f60336a699
const hasNativeCSSProperty = () => {
// https://csstriggers.com
const opacity = 1,
body = document.body;

let hasNativeCSSProperty = false;

body.style.setProperty('--opacity', opacity);
body.style.setProperty('opacity', 'var(--opacity)');

hasNativeCSSProperty = getComputerStyle(body).opacity === opacity;
body.style.setProperty('--opacity', '');
body.style.opacity = '';

return hasNativeCSSProperty;
}

if (hasNativeCSSProperty()) {
/* 支持 */
} else {
/* 不支持 */
}
}

参考