了解自定义CSS属性


今天的前端开发人员有太多的工具来帮助他们创建和编辑CSS。这些工具之一是预处理程序,使用预处理程序的一个主要好处是能够在你的风格中使用变量。这消除了复制和粘贴的需要,从而使重构更加容易。

当使用预处理器变量时,开发人员倾向于用颜色、字体大小、布局细节等来定义它们。这一切都很好,但是预处理器变量有一些限制:

  • 不能被JavaScript操纵。预处理器变量在到达浏览器之前被提前编译,作为CSS属性/值对。
  • 不知道DOM或CSSOM。就像上面一样,变量是提前编译的,没有机会知道这些细节。
  • 无法继承。在选择器上定义预处理变量并不意味着该选择器的后代也可以使用该变量。

旧学校社会保障系统变量

在继续讨论手头的话题之前,最好知道CSS有一个准变量,那就是currentColor关键字。这个受支持的变量指的是元素的当前颜色值。

.block {
color: cornflowerblue;
border: 1px solid currentColor; /*Border color will be the same as font color*/
}

尽管currentColor是强大的,但它也有它的局限性,包括只接受颜色值。

定义自定义CSS属性

CSS规范的伟大创造者,也就是W3,并不是天生就创造CSS变量。所创建的是自定义属性,按其术语来说是:

...一系列自定义作者定义的属性,统称为自定义属性,允许作者为具有作者选择的名称的属性分配任意值,并且var()函数,它允许作者在文档的其他地方使用这些值。

自定义属性就像任何其他CSS属性一样,可以在任何元素上定义。它们使用我们都珍视的相同的继承和级联。它们可以是有条件的、在媒体查询中设置的以及其他规则。此外,它们可以设置为内嵌和内嵌style标签。

CSS自定义属性有两个主要部分:定义它们和读取它们。

声明自定义属性

通过以名称开头来声明自定义属性--然后给它赋值。

:root {
--bodyColor: cornflowerblue;
}

属性名区分大小写。因此--bodyColor--BodyColor是两种不同的自定义属性。

读取自定义属性

若要读取CSS自定义属性,只需使用var功能:

:root {
--linkColor: orange;
}
a {
color: var(--linkColor);
}

上面,我们定义了一个自定义属性linkColor在。。。上:root伪类,然后使用var函数获取设置链接颜色值的属性值。自从我们定义了linkColor在。。。上:root伪类,我们可以访问linkColor链接选择器中的变量。但是,看看这个例子:

a {
--linkColor: orange
}
button {
color: var(--linkColor)
}

在上面的例子中,我们定义了linkColor但是我们尝试在按钮选择器中引用它。自从我们定义了linkColor在链接选择器中,linkColor将不会被定义。所以我们最终会得到一个颜色值inherited

需要指出的是,对于自定义属性,如果找不到计算值,计算值将是initial或者inherited这取决于手头的具体财产。

为了帮助解决这种自定义属性在使用时可能没有定义或没有值的情况,请使用var函数有一个回退参数。

h1 {
color: var(--headingColor, red);
}

在上述情况下,如果headingColor从未定义或给定值h1会变回红色。

不使用JavaScript更改自定义CSS属性

让我们从一个非常简单的悬停时更改自定义属性的示例开始:

button {
color: red;
width: 3em;
--buttonBackground: red;
background-color: var(--buttonBackground);
transition: background-color .2s ease;
}

button:hover {
--buttonBackground: blue;
}

如您所见,按钮的悬停重新定义了buttonBackground蓝色。

是的,我知道这是一个相当简单的例子,没有自定义属性也可以完成。但是,如果我们同时改变其他几个属性和值,会发生什么呢?这种能力允许我们创建更多可读的代码。让我们看一个更高级的例子。

:root {
--borderRadius: 10px;
}

@media screen and (min-width: 768px) {
--borderRadius: 15px;
}

button {
border-radius: var(--borderRadius);
}

现在,让我们考虑一下上面的内容。如你所见,我们开始了borderRadius到10个像素。然后我们在按钮的值中使用这个自定义属性border-radius价值。但最酷的是,我们还将媒体查询中的自定义属性重新定义为稍大一些。因此,如果我们碰到一个768或更大的断点,那么我们的按钮将有一个稍大的边界半径。

用JavaScript更改自定义CSS属性

现在自定义属性开始发光的地方是它们能够与JavaScript一起使用。

在JavaScript中使用CSS自定义属性时,我们需要做的两个主要部分是读取属性并在属性上设置一个新值。

获取自定义属性的值

要获取内联自定义属性值,只需使用以下命令:

element.style.getPropertyValue('--foo');

若要从样式表内或继承样式表时获取自定义属性值:

getComputedStyle(element).getPropertyValue('--foo');

我将使用上面的方法来获取值,因为它适用于内联值
不像第一次报道的那样。

设置自定义属性的值

设置自定义属性的值非常简单:

element.style.setProperty('--foo', 1 + 3);

上面将设置的值foo到元素上的4内联。很简单,
对吧。

用演示结束它

让我们看一个小例子,把所有这些放在一起。

在上面的笔中,你可以在结果视图中看到,如果你移动鼠标,白点将跟随你的光标。一个简单的演示,展示了我们刚刚在这篇文章中谈到的一些事情。让我们把它分解。

让我们看看JavaScript部分:

var rootEl = document.documentElement;

document.addEventListener('mousemove', e => {
let x = e.clientX / innerWidth;
let y = e.clientY / innerHeight;

rootEl.style.setProperty('--mouse-x', x);
rootEl.style.setProperty('--mouse-y', y);
});

我们在这里做的是将一个简单的鼠标移动事件绑定到文档。当鼠标移动时,我们将鼠标位置设为垂直或水平,然后用该值除以视图端口的宽度或高度,得到一个从0到1的数字。这将允许我们使用这个数字作为百分比。完成这些计算后,我们为鼠标x和y设置CSS自定义属性值,如下所示:

rootEl.style.setProperty('--mouse-x', x);
rootEl.style.setProperty('--mouse-y', y);

完成后,我们现在可以在CSS中访问我们的鼠标位置了。这有多酷?让我们看看我们在CSS中是如何做到的:

.demo:before {
--ballWidth: 3em;
content: '';
display: block;
position: absolute;
top: calc((100% * var(--mouse-y)) - (var(--ballWidth) * .5));
left: calc((100% * var(--mouse-x)) - (var(--ballWidth) * .5));
height: var(--ballWidth);
width: var(--ballWidth);
background-color: white;
border-radius: var(--ballWidth);
}

正如您在上面的CSS片段中看到的,我们引用了我们在JavaScript中设置的鼠标位置属性。我们只是用这两个词来称呼它们:

top: calc((100% * var(--mouse-y)) - (var(--ballWidth) * .5));
left: calc((100% * var(--mouse-x)) - (var(--ballWidth) * .5));

我们取相应的鼠标位置作为我们想要移动元素的方向,然后乘以100%将我们的数字转换成百分比。因此,当我们的鼠标移动时,我们正在更新鼠标变量,我们的CSS正在为我们移动元素。

结束语

CSS自定义属性是一种非常强大的方式,可以让你的样式表更加有趣。它们是分离JavaScript行为和样式的一种方式,如在JavaScript中为CSS设置信息以用于其样式的能力所示。

即使您正在为您的CSS使用预处理器,仍然有一个地方可以让CSS自定义属性直接嵌入到您的CSS中。原因是自定义属性可以与DOM或CSSOM交互,并且可以像预处理器变量一样动态更改。

你怎么想呢?