借助 Houdini 的新 API 实现更智能的自定义属性

CSS 中的过渡效果和数据保护

CSS 自定义属性(也称为 CSS 变量)可让您在 CSS 中定义自己的属性,并在整个 CSS 中使用这些属性的值。虽然它们在今天非常有用,但也有一些缺点,导致难以使用:它们可以采用任何值,因此可能会被意外覆盖;它们始终从父级继承值;并且您无法对其进行过渡。借助 Houdini 的 CSS 属性和值 API 级别 1(现已在 Chrome 78 中提供),这些缺点得以克服,使 CSS 自定义属性变得非常强大!

什么是 Houdini?

在介绍新 API 之前,我们先快速了解一下 Houdini。CSS-TAG Houdini 工作组(也称为 CSS Houdini 或简称为 Houdini)的宗旨是“开发能够解释网页上样式和布局‘神奇之处’的功能”。Houdini 规范旨在释放浏览器渲染引擎的强大功能,让开发者能够更深入地了解样式,并扩展渲染引擎。这样一来,在 JavaScript 中使用类型化 CSS 值以及填充或创建新的 CSS 而不会影响性能,终于成为可能。Houdini 有望在网络上激发无限创意。

CSS 属性和值 API 级别 1

借助 CSS 属性和值 API 级别 1(Houdini 属性和值),我们可以为自定义属性赋予结构。以下是使用自定义属性时的当前情况:

.thing {
  --my-color: green;
}

由于自定义属性没有类型,因此可能会以意想不到的方式被替换。例如,假设您使用网址定义了 --my-color,请考虑会发生什么情况。

.thing {
  --my-color: url('not-a-color');
  color: var(--my-color);
}

在这里,由于 --my-color 未指定类型,因此系统不知道网址不是有效的颜色值!使用时,它会回退到默认值(color 为黑色,background 为透明)。借助 Houdini Props 和 Vals,可以注册自定义属性,以便浏览器知道它应该是什么!

现在,自定义属性 --my-color 已注册为颜色!这会告知浏览器允许哪些类型的值,以及如何对该属性进行类型化和处理!

已注册的媒体资源详解

注册房源的流程如下所示:

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

它支持下列选项:

name: string

自定义属性的名称。

syntax: string

如何解析自定义属性。您可以在 CSS 值和单位规范中找到可能值的完整列表。默认设置为 *

inherits: boolean

是否继承父级的值。默认为 true

initialValue: string

自定义属性的初始值。

详细了解 syntax有效选项有很多,包括数字、颜色和 <custom-ident> 类型。您还可以使用以下值修改这些语法

  • 附加 + 表示它接受以空格分隔的相应语法的值列表。例如,<length>+ 是以空格分隔的长度列表
  • 附加 # 表示它接受以英文逗号分隔的相应语法的值列表。例如,<color># 是以英文逗号分隔的颜色列表
  • 在语法或标识符之间添加 | 表示提供的任何选项都是有效的。例如,<color># | <url> | magic 将允许使用以英文逗号分隔的颜色列表、网址或 magic 一词。

陷阱

Houdini 实参和值存在两个陷阱。首先,一旦定义了注册属性,就无法更新现有注册属性,尝试重新注册属性会抛出错误,表明该属性已被定义。

其次,与标准属性不同,注册属性在解析时不会进行验证。而是在计算时进行验证。这意味着,在检查元素的属性时,无效值不会显示为无效,并且在有效属性后添加无效属性不会回退到有效属性;不过,无效属性会回退到已注册属性的默认值。

为自定义属性添加动画效果

除了类型检查之外,注册的自定义属性还提供了一项有趣的功能:能够为其设置动画效果!一个基本动画示例如下所示:

<script>
CSS.registerProperty({
  name: '--stop-color',
  syntax: '<color>',
  inherits: false,
  initialValue: 'blue',
});
</script>

<style>
button {
  --stop-color: red;
  transition: --stop-color 1s;
}

button:hover {
  --stop-color: green;
}
</style>

当您将鼠标悬停在该按钮上时,它会从红色变为绿色!如果不注册该属性,颜色会从一种颜色跳到另一种颜色,因为如果不注册,浏览器就不知道一个值和下一个值之间会发生什么,因此无法保证能够实现颜色过渡。 不过,这个示例还可以进一步扩展,以实现 CSS 渐变动画!以下 CSS 可以使用相同的已注册属性编写:

button {
  --stop-color: red;
  background: linear-gradient(var(--stop-color), black);
  transition: --stop-color 1s;
}

button:hover {
  --stop-color: green;
}

这将为属于 linear-gradient 的自定义属性设置动画效果,从而为线性渐变设置动画效果。请查看下面的 Codepen,了解完整代码的实际应用,并自行试用。

总结

Houdini 即将登陆浏览器,届时,我们将能够以全新的方式使用和扩展 CSS。随着 Paint API 的发布以及现在的自定义属性和值,我们的创意工具箱正在不断扩展,使我们能够定义类型化的 CSS 属性,并使用它们来创建和动画化新颖而令人兴奋的设计。在 Houdini 问题队列中,您还可以提供反馈并了解 Houdini 的后续计划。Houdini 的存在是为了开发能够解释 Web 上样式和布局“魔力”的功能,因此请充分利用这些神奇的功能。

照片由 Maik Jonietz 拍摄,选自 Unsplash