传统CSS只能设置元素样式,用“属性名:属性值”的形式,没有变量、函数支撑的CSS不够灵活强大,Sass、Less等CSS扩展语言弥补了CSS这种的不足。CSS3的出现,为CSS带来了类似JavaScript语言中变量、函数的功能,以往需要JavaScript来实现的功能,CSS3已经可以自己实现了。据说下一代CSS还将加入三角函数……

1. 简单自定义属性

1.1 创建自定义属性

首先是一种CSS函数:var()

var()函数,MDN上是这么介绍的: var()函数可以代替元素中任何属性中的值的任何部分。它的参数为一个自定义属性名,然后可以引用该属性的值。

关于自定义属性,来看一个简单的例子:

:root {
	--b-link-color: #123;
	--b-link-hover-color: #234;
	--link-color: #333;
	--icon-size: 13px;
}

这种名称以”--“开头的,不在CSS规范里的属性即为自定义属性(CSS变量),它们可以像标准CSS属性一样被使用。这里定义了3种颜色,1种大小。

与定义JavaScript变量类似,自定义属性一旦定义,那么在它的作用域范围内均可使用。上图自定义属性定义在root根元素内,意味着整个HTML文档内都能访问这个属性。是不是类似于JavaScript里的全局变量?那么要创建局部可访问的自定义属性,只需要在这个局部的父元素内创建自定义属性即可,如下图在IDmusic-player的元素中创建它们:

#music-player {
	background: linear-gradient(to right, #888, #333);
	position: absolute;
	padding: 5px 0;
	border-radius: 20px;
	top: 10%;
	left: 10%;
	--b-link-color: #123;
	--b-link-hover-color: #234;
	--link-color: #333;
	--icon-size: 13px;
}

在此创建的自定义属性只能在#music-player及其子元素中访问。

回到前面的var()函数,用var()函数来引用自定义属性的值:

.player-song-detail figcaption {
	font-size: 13px;
	color: var(--b-link-color);
	margin-top: 5px;
}

color属性引用了自定义属性––b-link-color的值,即#123,相当于color: #123

单看这里,单单设置一个元素的color属性就创建了一个自定义属性看上去很多此一举,但是自定义属性的强大之处在于,它是CSS变量,定义一次,它的作用范围内都能引用,顶层更新,下层同步更新。如果作用范围内有很多元素要使用这个color属性,不必每个元素下都单独设置一个color: #123,只需设置color: var(––b-link-color),一旦 ––b-link-color 属性值更新,那么所有引用这个属性的元素都将更新color属性值。

1.2 更新自定义属性

那么如何更新自定义属性值呢,当然可以在CSS里面手动更新,但是更多的情况是需要由JavaScript来动态更新它。由于自定义属性不是CSS内置的标准属性,直接使用平常的JavaScript语法是行不通的,需要使用setProperty方法:

//标准JavaScript语法更新元素样式,这里更新color属性值:
document.getElementById("foo").style.color = "#fff";
//自定义属性值更新采用如下方法,这里把--b-link-color值改为#fff:
document.getElementById("foo").style.setProperty("--b-link-color", "#fff");

2. 使用自定义属性间接操作伪元素样式

众所周知,JavaScript是无法直接操作伪元素的样式,因为伪元素是虚拟的DOM,页面上并不存在,但是借由自定义属性充当中间人,JavaScript可以间接操作伪元素样式。

定义好自定义属性:

.player-mode {
	--mode-name: "\5355\66f2\5faa\73af";
	position: relative;
	cursor: pointer;
	margin-bottom: 5px;
	color: var(--b-link-color);
	font-size: var(--icon-size);
}

player-mode类中定义了––mode-name这个自定义属性,它的值是一串Unicode字符编码(防止中文出现乱码,我把汉字都转为Unicode)。

然后在伪元素中引用它:

.player-mode::after,
.player-song-list::after {
	content: var(--mode-name);
	position: absolute;
	white-space: nowrap;
}

这是两个after伪元素,它们的content属性都引用了上面定义的––mode-name的值。

上面的准备工作已经完成,after伪元素的content属性引用了自定义属性的值。正常情况下,JavaScript是无法操作这个content属性的,但是自定义属性的特点是“顶层更新,下层同步更新”,所以更新player-mode类中的––mode-name属性值,content属性值也会同步更新,代码如下:

document.querySelector(".player-mode").style.setProperty("--mode-name", "\987a\5e8f\64ad\653e");

发表评论

电子邮件地址不会被公开。 必填项已用*标注