CSS 自定义属性 @property 的使用
介绍
CSS 属性和值 API 是 CSS Houdini API(一组底层渲染 API)的一部分,包括 JS 接口CSS.registerProperty 和 CSS 接口 @property 两部分。
CSS.registerProperty
用于注册自定义属性,允许检查属性类型、默认值以及继承或不继承其值。
语法
CSS.registerProperty(PropertyDefinition)
PropertyDefinition 是一个字典对象,包含以下字段:
- name
- 一个字符串,表示正在定义的属性的名称。
- syntax
- 表示已定义属性的预期语法的字符串。默认为
*
。
- 表示已定义属性的预期语法的字符串。默认为
- inherits
- 一个布尔值,定义是否应该继承定义的属性。默认为 false.
- initialValue
- 表示已定义属性的初始值的字符串。
@property
@property 规则提供了一个直接在样式表中注册自定义属性的方式,跟 CSS.registerProperty 函数使用同样的参数调用效果相同。并可以对属性类型检查、设定默认值及定义是否可以被继承。
语法
@property --my-color {
syntax: "<color>";
inherits: false;
initial-value: #c0ffee;
}
以上相当于以下 JS 代码:
window.CSS.registerProperty({
name: '--my-color',
syntax: '<color>',
inherits: false,
initialValue: '#c0ffee',
});
syntax
和inherits
描述符是必需的。如果其中任何一项缺失,整条规则都将失效并且会被忽略。initial-value
描述符仅在syntax
描述符为通用语法定义(*
)或接受了任何有效的标记值时是可选的,否则也是必需的——如果此时该描述符缺失,整条规则都将失效且被忽略。- 未知描述符被视为无效并被忽略,但不会使 @property 规则无效。
syntax
描述了 @property 规则所允许的语法结构。
语法
syntax: '<color>'; /* 接收一个颜色值 */
syntax: '<color#>'; /* 接受逗号分隔的颜色值列表 */
syntax: '<length+>'; /* 接受以空格分隔的长度值列表 */
syntax: '<length | length+>'; /* 接受单个长度或以空格分隔的长度列表 */
syntax: '<length> | <percentage>'; /* 接收长度或百分比参数,但是二者之间不进行计算合并 */
syntax: 'small | medium | large'; /* 接收这些参数值之一作为自定义标识符 */
syntax: '*'; /* 任何有效字符 */
类型
<length>
- 由一个
<number>
和一个长度单位构成。与所有 CSS 维度一样,单位的字面值与数字之间没有空格。数字为 0 时,长度单位是可选的。例如1em 10px;
。
- 由一个
<number>
- 可以是整数或带有小数部分的数字。
<percentage>
- 一个百分比值。
<length-percentage>
- 可以是
<length>
或<percentage>
,例如 200px、20%、calc(100% - 200px)。
- 可以是
<color>
- 使用关键字(比如 blue 或 transparent)、以
#
加十六进制或者 rgb() 和 rgba() 函数表达式的形式,或以 hsl() 和 hsla() 函数表达式的形式。
- 使用关键字(比如 blue 或 transparent)、以
<image>
- CSS 渐变(图像)、矢量图形(比如 SVG 格式的图像)和 jpeg 等格式的图像。例如 url(test.jpg)、linear-gradient(to bottom, blue, red)。
<url>
- 指向一个资源。它没有独有的表达形式,只能通过 url() 函数定义。
<integer>
- 没有带单位的正整数或负整数。
<angle>
- 表示角的大小,单位为度(deg)、百分度(grad)、弧度(rad)或圈数(turn)。在
<gradient>
和 transform 的某些方法等场景中使用。
- 表示角的大小,单位为度(deg)、百分度(grad)、弧度(rad)或圈数(turn)。在
<time>
- 表示以秒(s)或毫秒(ms)为单位的时间的值,可为小数和负值。于 animation、transition 及相关属性中使用。
<resolution>
-
表示输出设备的像素密度。由严格为正
<number>
组成,后跟下面列出的单位之一。与所有 CSS 维度一样,单位字面值与数字之间没有空格。用于媒体查询中使用,例如@media print and (min-resolution: 300dpi) { ... }
。- dpi:表示每英寸的点数。 - dpcm:每厘米上的点数。1 英寸是 2.54 厘米,1dpcm ≈ 2.54dpi。 - dppx:表示每个px的点数。 由于 CSS px 的固定比率为 1:96,因此 1dppx 相当于 96dpi。 - x:dppx 的别名。
-
<transform-function>
- 用于对元素的显示做变换的 CSS 函数,matrix()、matrix3d()、perspective()、rotate()、rotate3d()、rotateX()、rotateY()、rotateZ()、scale()、scale3d()、scaleX()、scaleY()、scaleZ()、skew()、skewX()、skewY()、translate()、translate3d()、translateX()、translateY()、translateZ()。
<custom-ident>
- 任何用户自定义字符串标识符,要区分大小写。
<transform-list>
- 有效的
<transform-function>
值的列表。
- 有效的
inherits
控制由 @property 声明注册的自定义属性默认情况下是否会被继承。可为以下取值:
true
- 属性默认继承。
false
- 属性默认不继承。
auto
- 默认值,自动设置。
initial-value
initial-value 的值是对于设定的 syntax 具有正确值的字符串。依照 syntax 描述符定义,必须可以正确地解析。因此,如果 syntax 描述符为 <color>
,那么初始值必须是一个有效的 color 值。
使用
@property 的类型为浏览器提供了更多的上下文信息,这可以使我们为浏览器提供所需的信息来转换和动画这些属性。这也为那些不支持 transition 过渡或 animation 动画的 CSS 属性提供了一种解决方案。
- 下面例子中有四个饼图:没有使用变量定义的饼图、使用普通变量定义 conic-gradient 颜色的饼图、使用 @property 变量定义 conic-gradient 颜色的饼图和使用 JS 方法 CSS.registerProperty 注册属性定义 conic-gradient 颜色的饼图。可以看到只有使用 @property 属性和使用 JS 方法 CSS.registerProperty 注册属性定义的 CSS 值可以实现动画效果,而普通变量定义的 CSS 值没有动画效果。
@property --property {
syntax: "<percentage> | <angle>";
inherits: false;
initial-value: 18deg;
}
.property {
background: conic-gradient(red, red var(--property), transparent var(--property), transparent 100%);
transition: --property .5s linear;
}
.property:hover {
--property: 360deg;
}
CSS.registerProperty && CSS.registerProperty({
name: '--color',
syntax: '<color>',
inherits: false,
initialValue: 'red',
});
- 由于 @property 的值可以通过伪元素的 content 属性传递到 DOM,所以我们有了一种通过 CSS 来改变 DOM 的方法。
@keyframes load {
0%,
10% {
--angle: 0deg;
--hue: 0;
--dot: '';
}
40% {
--hue: 30;
--dot: '.';
}
70% {
--hue: 60;
--dot: '..';
}
100% {
--angle: 360deg;
--hue: 90;
--dot: '...';
}
}
浏览器支持
Firefox 和 Safari 浏览器在 PC 和移动端均不支持 @property 属性。