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

CSS 中的过渡和数据保护

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

什么是 Houdini?

在讨论新 API 之前,我们先简单介绍一下 Houdini。CSS-TAG Houdini 工作组(通常称为 CSS Houdini 或简称为 Houdini)旨在“开发一些功能,用于解释 Web 上样式和布局的‘魔力’”。Houdini 规范集合旨在充分发挥浏览器渲染引擎的强大功能,让您既能更深入地了解样式,又能扩展渲染引擎。 这样一来,在 JavaScript 中使用类型化 CSS 值以及在不影响性能的情况下进行 polyfill 或发明新 CSS 终于成为可能。Houdini 有望为 Web 上的创意 提供强大助力

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 属性和值,可以注册自定义属性,以便浏览器知道它应该是什么!

现在,自定义属性 --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。

Gotchas

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 上的样式和布局的“魔力”,所以请走出去,好好利用这些神奇的功能。