使用 Houdini 新 API 实现更智能的自定义属性

CSS 中的过渡和数据保护

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

什么是 Houdini?

在讨论新 API 之前,让我们先快速了解一下 Houdini。CSS-TAG Houdini 任务组(更广为人知的名称是 CSS Houdini 或简称为 Houdini)的存在是为了“开发解释 Web 上样式和布局‘魔力’的功能”。Houdini 规范的集合旨在释放浏览器渲染引擎的强大功能,从而可以更深入地了解我们的样式,并能够扩展我们的渲染引擎。有了这个,在 JavaScript 中使用类型化的 CSS 值以及对新的 CSS 进行 Polyfill 或发明而不会造成性能损失,最终成为可能。Houdini 有潜力为 Web 上的创造力提供强大的支持。

CSS 属性和值 API Level 1

CSS 属性和值 API Level 1(Houdini Props and Vals)允许我们为自定义属性赋予结构。这是当前使用自定义属性的情况

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

由于自定义属性没有类型,因此它们可能会以意想不到的方式被覆盖。例如,考虑一下如果您使用 URL 定义 --my-color 会发生什么。

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

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

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

注册属性的结构

注册属性如下所示

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

它支持以下选项

name:字符串

自定义属性的名称。

syntax:字符串

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

inherits:布尔值

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

initialValue:字符串

自定义属性的初始值。

仔细查看 syntax。有许多有效选项,范围从数字到颜色,再到 <custom-ident> 类型。这些语法也可以通过使用以下值进行修改

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

注意事项

Houdini Props and Vals 有两个注意事项。第一个是,一旦定义,就无法更新现有的已注册属性,并且尝试重新注册属性将抛出一个错误,表明它已被定义。

其次,与标准属性不同,已注册属性在解析时不会进行验证。相反,它们在计算时才进行验证。这意味着,无效值在检查元素的属性时不会显示为无效,并且在有效属性之后包含无效属性也不会回退到有效属性;但是,无效属性将回退到已注册属性的默认值。

动画自定义属性

已注册的自定义属性除了类型检查之外,还提供了一个有趣的额外功能:动画它的能力!一个基本的动画示例看起来像这样

<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 的一部分,从而动画我们的线性渐变。查看下面的 Glitch 以查看完整代码的实际效果并亲自尝试一下。

结论

Houdini 正在向浏览器迈进,随之而来的是使用和扩展 CSS 的全新方式。随着 Paint API 已经发布,以及现在的自定义属性和值,我们的创意工具箱正在扩展,使我们能够定义类型化的 CSS 属性,并使用它们来创建和动画新的、令人兴奋的设计。Houdini 问题队列中还有更多内容,您可以在其中提供反馈并了解 Houdini 的下一步发展。Houdini 的存在是为了开发解释 Web 上样式和布局“魔力”的功能,因此请走出去,充分利用这些神奇的功能。

照片由 Maik JonietzUnsplash 上拍摄