我总结的 CSS 变量知识点

摄影 | Eliott Reynajavascript

最近读到一篇文章《Everything you need to know about CSS Variables》,让我对 CSS 变量有了新的认识。下面将整理出来的跟本身感悟的地方与你们分享,但愿能帮助到对 CSS 变量还只知其一;不知其二的同窗。css

答疑

1、为何 CSS 变量还称为“自定义属性(custom properties)”?

咱们回忆 CSS 变量的使用方式:html

span {
    /* 局部变量 --color */
    --color: gold;
    color: var(--color);
}
复制代码

声明 CSS 变量的时候,发现跟使用普通属性是同样的,这里说的“同样”是指:使用的位置同样,而且使用的方式也同样。java

只不过跟普通属性相比,CSS 变量多了两个连字符 -- 做为前缀,本质上就是个属性。并且这类属性都是开发者本身起的,属性值也是咱们设置的,天然就是“自定义属性”了。浏览器

不过特殊的地方在于,咱们可使用 var() 函数解析出这类属性的属性值:ide

color: var(--color);
/* 至关于 */
color: gold;
复制代码

还有一点,CSS 变量既然是属性,那么就能够像行内样式那样使用:函数

<span style="--color: gold; color: var(--color);">这段文本是金色的</span>
复制代码

文章后面“使用 JS 操做 CSS 变量”一节,就是基于此种写法实现的。以后会讲到,我们先继续往下看。ui

2、全局变量和局部变量

全局变量是这样声明的:spa

:root {
    --color: gray;
}
复制代码

:root 伪类命中的是文档根元素 <html>,也就说3d

:root {
    --color: gray;
}
/* 至关于 */
html {
    --color: gray;
}
复制代码

根元素是文档的最顶层元素,在它下面声明的变量就是全局变量。对应的,不是全局的变量就是局部变量。

<style> :root { /* 全局变量 --color */ --color: gray; } p { /* 局部变量 --color */ --color: gold; color: var(--color); } </style>

这段文本是灰色的,<span>这段文本是金色的</span>
复制代码

与 JS 做用域相似的是,局部变量会覆盖全局中的同名变量。所以上面 <span> 里的文本是金色的。

3、var() 解析出来的结果只能做为属性值使用

下面这样写是不行的:

.mt-20px {
    --mt: margin-top;
    var(--mt): 20px; /* × 这种写法是错误的 */
}
复制代码

咱们想要多是这种结果:margin-top: 20px,但观察发现,浏览器并不会解析 var(--mt),并且提示这是一个未知属性名。

下面这样写就没有问题了:

.mt-20px {
    --20px: 20px;
    margin-top: var(--20px); /* √ 这样写就没问题了 */
}
复制代码

4、var() 的回退值(fallback)

var() 功能符,还接受第二个参数,表示一个回退值——当变量不能成功解析时,就会使用这个回退值。

.header {
    color: var(--header-color, blue);
}
复制代码

上面代码中,若是 --header-color 没有声明的话,就会使用回退值 blue,做用有点相似于 JS 函数中的参数默认值。

5、使用 calc() 作数学运算

若是声明的变量值中包含数学运算,就要包装在 calc() 函数中。不然是无效运算。

像下面这种写法就不对:

.font-40px {
    --size: 20px * 2; /* × 错误的写法 */
    font-size: var(--size);
}
复制代码

在浏览器中观察,不会看见显式的报错,但 font-size 的最终解析值还是默认的 16px

这种错误写法在浏览器中并不会显式报错

`font-size` 的最终的解析值还是 `16px`

须要这样写:

.font-40px {
    --size: calc(20px * 2); /* √ 正确的写法 */
    font-size: var(--size);
}
复制代码

calc() 函数的引入,为在 CSS 中进行各类不一样单位的混合数值运算(加、减、乘、除),带来了极大的便捷:

.example {
    /* 加 */
    width: calc(100% + 1em);
    /* 减 */
    width: calc(100% - 80px);
    /* 乘 */
    width: calc(100% * .5);
    /* 除 */
    width: calc(100% / 6);
}
复制代码

这里抛砖引玉,更多的使用细节能够查看 MDN 上的文档

6、使用 JS 操做 CSS 变量

JS 操做 CSS 变量的原理,是使用 DOM 对象的 style 属性,它是一个 CSSStyleDeclaration 类型的对象。

咱们以前可能作过这样的操做:

document.body.style.color = 'gold'
复制代码

color 是标准属性,能够直接使用这种方式设置。CSS 变量则属于非标准属性,使用这种方法就不会起做用:

// × 错误的写法,由于 --color 并非标准属性
document.body.style['--color'] = 'gold'
复制代码

CSSStyleDeclaration 上提供了一个 setProperty() 方法,能够用来设置非标准属性。语法以下:

style.setProperty(propertyName, value, priority);

所以,咱们能够这么作:

document.body.style.setProperty('--color', 'gold');
复制代码

执行结果以下:

这样,我们就能经过 JS 操做 CSS 变量了。

实践

CSS 变量的使用,在必定程度上改变了咱们书写、组织代码的形式。其原理在于,咱们可以修改已有变量的值。

下面我举两个比较有表明性的案例:

  1. 主题按钮
  2. 元素的 transform 变换

主题按钮

咱们有四个主题色的按钮,在不一样的场景下使用。使用之前的写法,是经过覆盖属性的方式实现的:

.btn {
    color: #333;
    background-color: #eee;
    border: 0;
    padding: .5rem;
    cursor: pointer;
}

.btn-success {
    color: #fff;
    background-color: green;
}

.btn-error {
    color: #fff;
    background-color: red;
}

.btn-warning {
    background-color: orange;
}
复制代码

若是使用变量,就不须要覆盖属性,直接修改变量值便可。

.btn {
    color: var(--btn-color, #333);
    background-color: var(--btn-bg-color, #eee);
    border: 0;
    padding: .5rem;
}

.btn-success {
    --btn-color: #fff;
    --btn-bg-color: green;
}

.btn-error {
    --btn-color: #fff;
    --btn-bg-color: red;
}

.btn-warning {
    --btn-bg-color: orange;
}
复制代码

demo 地址查看这里:codepen.io/zhangbao/pe…

元素的 transform 变换

先看看最终的效果图:

demo 地址:codepen.io/zhangbao/pe…

实现原理是这样的:咱们在拖拉 Range Input 的时候,获取当前的 value 值,设置为变量 --slider 的值,.color-boxes 使用了此变量设置自身的 Y 轴偏移度。

涉及到的核心代码以下:

CSS:

.color-boxes {
    transform: perspective(500px) rotateY( calc(var(--slider) * 1deg));
}
复制代码

JS

const range = document.querySelector('.booth-slider')

range.addEventListener('input', handleSlider)
function handleSlider (e) {
  document.documentElement.style.setProperty('--slider', e.target.value)
}
复制代码

嗯,很神奇。

最后

本篇文章是我在看了一篇技术文章后总结的知识点,并加上了本身的一些感悟。若是看完后帮到了你,我将感到万分荣幸!😁

(完)

相关文章
相关标签/搜索