借助 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 执行 polyfill 或创建新 CSS。Houdini 有潜力 在网络上发挥创意

CSS 属性和值 API 级别 1

通过 CSS 属性和值 API 级别 1(Houdini Props 和 Vals),我们可以为自定义属性提供结构。以下是使用自定义属性时会出现的情况:

.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 Props 和 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 的自定义属性添加动画效果,从而为线性渐变添加动画效果。请查看下方的故障代码,了解完整代码的实际运行情况,并亲自试用。

总结

Houdini 即将面向浏览器推出使用和扩展 CSS 的全新方式。随着 Paint API 已经推出,现在又有 Custom Props 和 Vals。我们的广告素材工具箱正在不断扩展,让我们能够定义类型化 CSS 属性,并使用这些属性来打造令人惊叹的新设计并为其添加动画效果。此外,Houdini 问题队列中还将推出更多功能,您可以在该队列中提供反馈,了解 Houdini 的后续发展。Houdini 旨在开发一些功能,解释 Web 样式和布局的“神奇”,因此请充分利用这些神奇功能。

照片由 Maik Jonietz 拍摄于 Unsplash 网站