@property:为 CSS 变量赋予超能力

CSS Houdini 是一个总称,涵盖一组低层级 API,用于公开 CSS 渲染引擎的某些部分,并可让开发者访问 CSS 对象模型。对于 CSS 生态系统来说,这是一次巨大的变化,因为开发者可以告知浏览器如何读取和解析自定义 CSS,而无需等待浏览器供应商提供对这些功能的内置支持。太令人兴奋了!

在 Houdini 中,最令人期待的 CSS 新增功能之一便是 Properties 和 Values API

此 API 通过赋予语义含义(由语法定义)甚至回退值来强化 CSS 自定义属性(通常称为 CSS 变量),从而支持 CSS 测试。

编写 Houdini 自定义属性

以下是设置自定义属性的示例(假设:CSS 变量),但现在设置了语法(类型)、初始值(回退)和继承布尔值(它是否从其父项继承值?)。目前,可通过 JavaScript 中的 CSS.registerProperty() 执行此操作,但在支持浏览器中,您可以使用 @property

单独的 JavaScript 文件 (Chromium 78)
CSS.registerProperty({
  name: '--colorPrimary',
  syntax: '',
  initialValue: 'magenta',
  inherits: false
});
包含在 CSS 文件 (Chromium 85) 中
@property --colorPrimary {
  syntax: '';
  initial-value: magenta;
  inherits: false;
}

现在,您可以通过 var(--colorPrimary) 访问 --colorPrimary,就像访问任何其他 CSS 自定义属性一样。不过,这里的不同之处在于,--colorPrimary 不仅仅作为字符串读取。里面有数据!

后备值

与任何其他自定义属性一样,您可以获取(使用 var)或设置(写入/重写)值,但对于 Houdini 自定义属性,如果您在替换该属性时设置了 false 值,CSS 渲染引擎将发送初始值(其后备值),而不是忽略该行。

请参考以下示例。--colorPrimary 变量的 initial-valuemagenta。但开发者为它指定了无效的值“23”。如果没有 @property,CSS 解析器会忽略无效代码。现在,解析器会回退到 magenta。这支持在 CSS 中进行真正的回退和测试。太棒了!

.card {
  background-color: var(--colorPrimary); /* magenta */
}

.highlight-card {
  --colorPrimary: yellow;
  background-color: var(--colorPrimary); /* yellow */
}

.another-card {
  --colorPrimary: 23;
  background-color: var(--colorPrimary); /* magenta */
}

语法

借助语法功能,您现在可以通过指定类型来编写语义 CSS。目前允许使用的类型包括:

  • length
  • number
  • percentage
  • length-percentage
  • color
  • image
  • url
  • integer
  • angle
  • time
  • resolution
  • transform-list
  • transform-function
  • custom-ident(自定义标识符字符串)

设置语法可让浏览器对自定义属性进行类型检查。这样做有很多好处。

为说明这一点,我将向大家展示如何为渐变添加动画效果。目前,无法在梯度值之间平滑地添加动画(或插值),因为每个梯度声明都是解析为字符串。

使用采用“数字”语法的自定义属性时,左侧的渐变可在停止值之间平滑过渡。右侧的渐变使用的是默认自定义属性(未定义语法),并显示突然过渡。

在此示例中,通过悬停互动,渐变停止百分比正在从起始值 40% 转换到结束值 100%。您应该会看到该顶部渐变颜色向下的平滑过渡。

左侧的浏览器支持 Houdini Properties 和 Values API,可实现平滑的渐变停止过渡。右侧的浏览器则不会。不支持的浏览器只能将这种变化理解为一个字符串,即从 A 点到 B 点。无法插入值,因此您无法看到流畅的过渡。

不过,如果您在编写自定义属性时声明语法类型,然后使用这些自定义属性启用动画,就会看到过渡效果。您可以按如下方式实例化自定义属性 --gradPoint

/* Check for Houdini support & register property */
@supports (background: paint(something)) {
  @property --gradPoint {
    syntax: '<percentage>';
    inherits: false;
    initial-value: 40%;
  }
}

然后,当需要添加动画效果时,您可以将值从初始 40% 更新为 100%

@supports (background: paint(something)) {
  .post:hover,
  .post:focus {
    --gradPoint: 100%;
  }
}

这样便可实现平滑的渐变过渡。

平滑过渡的渐变边框。观看 Glitch 演示

总结

@property 规则允许您在 CSS 本身内编写语义有意义的 CSS,使一项令人兴奋的技术更易于访问。如需详细了解 CSS Houdini 以及 Properties 和 Values API,请参阅以下资源:

照片由 Cristian Escobar 拍摄,由 Unsplash。