前言

在古代浏览器中, 咱们会常常看到这样的属性:

element {  --main-bg-color: brown;}

这里咱们就来介绍一下他, 并提供一些相干的阐明

简介

自定义属性(有时候也被称作CSS变量或者级联变量)是由CSS作者定义的,它蕴含的值能够在整个文档中重复使用。由自定义属性标记设定值(比方: --main-color: black;),由var() 函数来获取值(比方: color: var(--main-color);)

申明

申明一个自定义属性,属性名须要以两个减号(--)开始,属性值则能够是任何无效的CSS值。
如前言中的 --main-bg-color 属性

通常的最佳实际是定义在根伪类 :root 下,这样就能够在HTML文档的任何中央拜访到它了:

/*:root 选择器匹配文档根元素。*//*在 HTML 中,根元素始终是 html 元素。*//*也就是说:root 示意的是根元素*/:root {  --main-bg-color: brown;}
留神:自定义属性名是大小写敏感的,--my-color 和 --My-color 会被认为是两个不同的自定义属性。
同时不能蕴含$,[,^,(,%等字符,一般字符局限在只有是“数字[0-9]”“字母[a-zA-Z]”“下划线_”和“短横线-”这些组合,然而能够是中文,日文或者韩文,例如
body {  --深蓝: #369;  background-color: var(--深蓝);}

应用

element {  background-color: var(--main-bg-color);}

这些自定义属性,仅当须要的时候才会计算,而并不会按其余规定进行保留。比方,你不能为元素设置一个属性,而后让它从兄弟或旁支子孙规定上获取值。属性仅用于匹配以后选择器及其子孙,这和通常的CSS是一样的。

默认值

用 var() 函数能够定义多个备用值(fallback value),当给定值未定义时将会用备用值替换。

/*如果提供了第二个参数,则示意备用值,当自定义属性值有效时失效。第二个参数能够嵌套,然而不能持续平铺开展上来了,例如:*/.two {  color: var(--my-var, red); /* Red if --my-var is not defined */}.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" */}

第二个例子展现了如何解决一个以上的 fallback。该技术可能会导致性能问题,因为它花了更多的工夫在解决这些变量上。

在 js 中操作

在 JavaScript 中获取或者批改 CSS 变量和操作一般 CSS 属性是一样的:

// 获取一个 Dom 节点上的 CSS 变量element.style.getPropertyValue("--my-var");// 获取任意 Dom 节点上的 CSS 变量getComputedStyle(element).getPropertyValue("--my-var");// 批改一个 Dom 节点上的 CSS 变量element.style.setProperty("--my-var", jsVar + 4);

CSS变量的空格尾随个性

body {  --size: 20;     font-size: var(--size)px;}

此处font-size:var(--size)px等同于font-size:20 px,留神,20前面有个空格,所以,这里的font-size应用的是<body>元素默认的大小。

应用场景

简略的实现一种进度条:

里面有一层背景层,而后外面有进度条,还有进度值。

在过来,会应用两层div元素,而后JS去扭转外面有色彩条条的宽度,同时设置进度值。

<label>图片1:</label><div class="bar" style="--percent: 60;"></div><label>图片2:</label><div class="bar" style="--percent: 40;"></div><label>图片3:</label><div class="bar" style="--percent: 20;"></div>
.bar {    height: 20px; width: 300px;    background-color: #f5f5f5;}.bar::before {    display: block;    counter-reset: progress var(--percent);    content: counter(progress) '%\2002';    width: calc(1% * var(--percent));    color: #fff;    background-color: #2486ff;    text-align: right;    white-space: nowrap;    overflow: hidden;}

能够看到,咱们只须要一层div标签,DOM层级简略了,而后,须要批改的HTML变动项仅仅是一个--percent自定义属性而已。

更多场景可参考此文章: https://www.zhangxinxu.com/wo...

扩大

咱们能够通过 @property 来扩大 CSS 变量:

他的语法:

@property --property-name {  syntax: '<color>';  inherits: false;  initial-value: #c0ffee;}

@property 规定中 syntaxinherits 描述符是必须的; 如果其中任何一项缺失, 整条规定都将生效并且会被疏忽。

initial-value 描述符仅在 syntax 描述符为通用 syntax 定义时是可选的,否则 initial-value 也是必须的——如果此时该描述符缺失,整条规定都将生效且被疏忽。

当然咱们也能够应用 js 来创立:

window.CSS.registerProperty({  name: '--my-color',  syntax: '<color>',  inherits: false,  initialValue: '#c0ffee',});

他的作用, 很多状况是为了实现了一些以往无奈简略实现的动画成果

具体能够参考此文章, 外面举了几个例子: https://juejin.cn/post/695120...

兼容性

目前 css 变量的兼容是最低 Chrome49:

在 CSS 中咱们也能够进行兼容性解决:

.selector: {}@supports ( (--a: 0)) {  /* supported */     .selector: {}}@supports ( not (--a: 0)) {  /* not supported */    .selector: {}}

在 js 中也能够进行对应判断

const isSupported =    window.CSS &&    window.CSS.supports &&    window.CSS.supports('--a', 0);

@property 还只是一个试验中的属性, 他的兼容要求是非常高的:

polyfill

https://github.com/jhildenbid...

应用此兼容间接能够达到的兼容:
Chrome 19+
Edge 12+
Firefox 6+
IE 9+
Safari 6+

目前的状况

less/sass

在大多数的我的项目中, 是应用 less/sass/scss 的, 然而在这几种 css 预处理工具中曾经有了变量的性能, 如果再加上 CSS 原生变量一起应用的话, 就会显得很冗余

针对这些预处理器, 咱们就应用原生 css 变量代替原有的变量, 其余的仍旧放弃不变

css in js

在 root 中定义结束根底 CSS 后, 就能够在 js 中应用了, 在这种框架有他是有很大定施展空间的

原子css

当初罕用的一种原子化 CSS 框架: tailwindcss

在这种框架中, 外部就宽泛应用CSS变量, 所以如果你能应用 Tailwind, 你就能应用 CSS变量

总结

CSS 变量这一性能, 当初的浏览器反对度曾经足够了, 同时针对现有的 CSS 多种预处理器, 有了肯定的适配度, 如果有应用的打算, 能够尝试引入了

当然当初没有一个比拟全面的解决方案, 想要再张望下也是没问题的

援用

  • https://developer.mozilla.org...
  • https://www.zhangxinxu.com/wo...
  • https://juejin.cn/post/693753...
  • https://www.zhangxinxu.com/wo...
  • https://developer.mozilla.org...