1. 介绍
CSS 定义了一套全面的属性,可以通过操作这些属性来修改网页文档的布局、绘制或行为。然而,网页作者常常希望通过额外的属性来扩展这套属性。
[css-variables] 提供了定义用户控制属性的基本方法, 但这些属性总是以令牌列表作为值,必须始终继承,并且只能通过 var() 引用重新并入其他属性的值中,来影响文档的布局或绘制。
本规范扩展了[css-variables],允许注册具有值类型、初始值和定义的继承行为的属性, 通过两种方法:
-
JS API,
registerProperty()
方法 -
CSS at-rule,@property 规则
本规范是[css-paint-api-1]和[css-layout-api-1]的补充, 允许自定义属性直接影响绘制和布局行为。
2. 注册的自定义属性
自定义属性可以成为一个注册的自定义属性,
使其更像用户代理定义的属性:
赋予它一个由用户代理检查的语法,
一个初始值,
和特定的继承行为。
这可以通过@property 规则,
或registerProperty()
JS 函数来实现。
自定义属性在文档
中被视为注册,
如果其名称在文档的样式表中有一个有效的@property 规则定义,
或其名称在文档的[[registeredPropertySet]]
槽中包含
(即,registerProperty()
被调用来注册它)。
注册的自定义属性 的行为类似于未注册的 自定义属性, 只是如下面定义的那样。
2.1. 确定注册
一个注册的自定义属性具有一个自定义属性注册, 包含处理它如真实属性所需的所有数据。 它是一个结构 ,由以下内容组成:
-
一个属性名称(一个自定义属性名称字符串)
-
一个语法(一个语法字符串)
-
一个继承标志(一个布尔值)
如果文档
的
[[registeredPropertySet]]
槽包含一个记录,其自定义属性的名称,
注册即该记录。
否则,
如果文档
的
活动样式表包含至少一个有效的@property 规则
表示与自定义属性的名称的注册,
文档顺序中的最后一个注册即为该注册。
2.2. 解析时行为
注册的自定义属性的解析方式与未注册的自定义属性完全相同; 几乎允许任何内容。 属性的注册语法在解析时不被检查。
注意:然而, 语法在计算值时被检查, 在通过var()进行替换之前。 参见§ 2.4 计算值时的行为。
为什么不对自定义属性进行语法检查?
在解析页面的 CSS 时, 用户代理通常会进行多项优化 以帮助提高速度和内存使用。
其中一个优化 是仅存储实际会产生影响的属性; 它们会丢弃无效的属性, 如果在单个声明块中多次写入同一属性, 除最后一个有效的属性外,所有其他属性都会被丢弃。 (这是 CSS 的错误恢复 和向前兼容行为的重要部分。)
如果属性的语法在页面的生命周期内从未变化,这种方法是有效的。 但是,如果自定义属性已注册, 它可以更改其语法, 以便之前无效的属性 突然变为有效。
处理这一点的唯一方法是要么存储每个声明, 即使那些最初无效的声明 (增加页面的内存成本), 要么使用新的语法规则重新解析整个页面的 CSS (增加注册自定义属性的处理成本)。 这两者都不是非常理想的选择。
此外, 用户代理定义的属性的语法由用户查看页面时的用户代理版本决定; 这超出了页面作者的控制范围, 这就是 CSS 的错误恢复行为的整个原因 和针对不同支持级别编写多个声明的实践。 而自定义属性的语法由页面作者控制, 根据他们在页面中包含的样式表或脚本; 没有不可预测性需要管理。 丢弃违反语法的自定义属性 因此只会对页面作者来说是一种便利, 而不是像用户代理定义的属性那样的必要性。
2.3. 指定值-时间行为
就像未注册的自定义属性一样, 所有注册自定义属性,无论注册语法如何, 都接受CSS宽关键字, 例如继承或还原。 其行为在CSS 级联 4 § 7.3 明确默认值中定义。
2.4. 计算值-时间行为
如果注册的语法是通用语法定义, 则计算值与未注册的自定义属性相同 (要么是替换变量后的指定值,要么是保证无效值)。
否则,尝试解析该属性的值 根据其注册语法。 如果失败, 声明在计算值时间无效,而计算值将相应确定。 如果成功, 计算值依赖于语法的具体情况:
对于"<length>"
、"<length-percentage>"
、"<angle>"
、
"<time>"
、"<resolution>"
、"<integer>"
、
"<number>"
、
和"<percentage>"
值:
-
如果指定值是任何其他数字字面量 (例如5或20%), 则计算值如指定。 (特别是,百分比永远不会与任何内容解析。)
-
如果指定值是一个计算为这些类型的函数 (例如数学函数), 则计算值由该函数定义。
对于"<color>"
值,
通过解析颜色值来计算值,
根据CSS 颜色 4 § 14.
解析<color>值。
对于"<custom-ident>"
、标识符或"*"
值,
计算值如指定。
对于"<url>"
值,
计算值为以下之一:
-
如果 URL 是相对 URL, 则计算值为解析后的绝对 URL,如[css3-values]中所述。
-
否则,计算值如指定。
URL 行为示例
例如,假设--url-foo和--url-bar是具有<url>语法的注册
自定义属性,并且我们有一个样式表在/style/foo/foo.css
:
div{ --url-foo : url ( "foo.png" ); }
还有另一个样式表在/style/bar/bar.css
div{ --url-bar : url ( "bar.png" ); }
最后,一个文档在/index.html
:
< link href = "/style/foo/foo.css" rel = "stylesheet" type = "text/css" > < link href = "/style/bar/bar.css" rel = "stylesheet" type = "text/css" > < div style = "background-image: var(--url-foo), var(---url-bar);" > </ div >
在这里,var(--url-foo) 引用会生成一个解析为/style/foo
的URL,而var(--url-bar) 引用会生成一个解析为/style/bar
的URL。
另一方面,如果--url-foo和--url-bar都是未注册的,它们将把它们的字面值(相对URL)替换到/index.html
样式表中,然后将这些URL解析为/index.html
。
对于"<image>"
值,计算值是计算的<image>。
对于"<transform-function>"
和"<transform-list>"
值,计算值按规定生成,但所有长度会解析为其计算值。
对于带有乘数的值,计算值是基本类型的计算值列表。
对于用| 组合符指定的语法,计算值由匹配该值的第一条子句的计算值规则应用给出。
2.5. 动画行为
注意: 根据[css3-animations]和[css3-transitions]的定义,可以指定引用自定义属性的动画和过渡。
当通过动画和过渡引用时,自定义属性值会插值 按计算值,根据解析的类型。
注意:
这意味着值的列表,如<color>+
或<color>#
,会插值为简单列表,逐个匹配每个组件索引,如果组件数量不匹配则会失败。
作为上述规则的例外,解析为<transform-list>
、<transform-function>
或<transform-function>+
的值则按transform属性插值。
注意:
如果出于某种原因,自定义属性定义为<transform-function>#
,则首先会插值为简单列表,然后每个列表项将插值为transform值。
注意: 注册(或更改注册)自定义属性可以改变其计算值,这可以开始或中断CSS过渡。
2.6. 条件规则
如§ 2.2 解析时行为中所述,无论是未注册的还是注册的 自定义属性在解析时都接受(几乎)所有可能的值。注册的 自定义属性仅在计算值时应用其语法。
因此,所有自定义属性,无论是注册还是未注册,都将在@supports规则中测试为“true”,只要不违反自定义属性的(非常宽松的)通用语法。
syntax : "<color>" ;
注册,像@supports (--foo: 1em) {...}
这样的规则仍会评估为true并应用这些样式,因为该声明确实成功解析为有效的属性。
2.7. 通过 var() 的替换
与未注册的自定义属性一样, 注册的自定义属性的值可以使用 var() 函数替换为另一个值。 然而,注册的自定义属性作为其 计算值 进行替换,而不是用于生成该值的原始标记序列。
任何引用注册自定义属性的 var() 函数 必须被替换为 等效标记序列, 它等于通过 序列化 计算值生成的标记序列, 并 标记化 结果字符串。
div{ font-size : 10 px ; --x : 8 em ; --y : var ( --x); }
因为 --x 的计算值(序列化时) 是 "80px",所以 --y 的计算值是 一个 <dimension-token>,其值为 "80" 和单位 "px"。
2.7.1. 在 var() 引用中的后备值
使用 var() 函数引用注册自定义属性 时 可以提供后备值。然而,后备值必须与被引用的自定义属性的 语法定义 匹配,否则声明在 计算值时间无效。
注意: 无论后备值是否被使用,这都适用。
2.7.2. 通过相对单位的依赖循环
注册自定义属性 遵循与未注册的 自定义属性 相同的依赖循环解析规则, 并附加以下约束:
对于任何具有 <length> 或 <length-percentage> 语法组件的注册自定义属性:
-
如果该属性包含以下任何单位: em, ex, cap, ch, ic, lh; 那么在该属性与当前元素的 font-size 之间添加一条边。
-
如果该属性包含 lh 单位, 在该属性与当前元素的 line-height 之间添加一条边。
-
如果该属性包含 rlh 单位, 在该属性与根元素的 line-height 之间添加一条边。
CSS. registerProperty({ name: "--my-font-size" , syntax: "<length>" , initialValue: "0px" , inherits: false });
以下代码将产生一个依赖循环:
div{ --my-font-size : 10 em ; font-size : var ( --my-font-size); }
而 font-size 的行为将表现得好像指定了 unset 值。
2.8. 影子 DOM
与 CSS 中的许多概念不同
(参见 CSS Scoping 1 § 3.5
名称定义构造和继承),
属性注册 不是 作用于树范围。
所有注册,
无论它们出现在最外层文档中
还是在影子树中,
都在一个全球注册图中交互,
适用于 文档
。
为什么注册不能作用于范围?
对于属性注册作用于范围的情况是明确的—使用影子 DOM 的组件 并注册一些自定义属性 可能并不打算让外部页面 查看该注册, 因为外部页面甚至不知道该组件正在使用该属性。
然而,也有不作用于注册范围的理由—自定义属性用于将数据 导入 组件, 外部页面能够设置这些自定义属性 并让注册进行语法检查是很有用的; 同样,属性的初始值等概念 只有在属性注册全局存在时才有意义, 因此它适用于文档根部的属性。
但以上只是意味着注册范围 可能是应当可控的东西, 而不是强制全局。
注册必须是全局的原因 是因为元素可以同时存在于多个树范围中, 各个树范围的样式 会交错并共同级联。 这适用于 宿主元素, 它生活在外部树中 但可以通过 :host 选择器从影子树中进行样式化, 同样,影子 DOM 内的元素 也可以通过外部树中的 ::part() 伪元素进行目标选择。
如果注册可以作用于树范围, 而一个单一属性在内外两处注册, 那么不清楚应该应用哪个注册 来解析值。 即使我们追踪值来自哪个树 (这是我们对其他树作用值所做的) 并应用相应的注册, 也不清楚这是否会产生合理的结果—影子 DOM 可能期望某个属性有 特定的值空间, 并且在接收到完全不同的值时会感到惊讶, 因为外部树赢得了级联 并应用了它自己的注册。
当自定义属性作为使用影子 DOM 的组件的公共 API 的一部分暴露时, 这种全局注册行为会按预期工作。 如果外部页面使用同名的自定义属性 进行不同目的, 那已经是需要解决的冲突, 而注册行为并没有使情况变得更糟。
然而,如果自定义属性旨在用于组件的私有内部使用, 建议给该属性 取一个可能唯一的名称, 以最小化与其他上下文发生冲突的可能性。 这可以通过包含项目名称 或一些简短的随机字符串 来实现。
3. @property 规则
@property 规则在样式表中直接表示 自定义属性注册
而无需运行任何 JS。
有效的 @property 规则会导致一个 注册的自定义属性,
就好像 registerProperty()
被调用并使用了等效的参数。
@property 的语法是:
@property <custom-property-name> { <declaration-list> }
有效的 @property 规则表示一个 自定义属性注册, 其属性名称为规则前导中的 <custom-property-name> 的序列化。
@property 规则需要 语法 和 继承 描述符; 如果缺少任一项, 整个规则都是无效的,必须被忽略。 初始值 描述符只有在语法为 通用语法定义 时是可选的, 否则该描述符是必需的; 如果缺失,整个规则无效,必须被忽略。
未知的描述符是无效的并被忽略, 但不会使 @property 规则无效。
注意: 如 § 2.1 确定注册
中规定,
如果为同一个 <custom-property-name> 定义多个有效的 @property 规则,
则样式表中最后一个的“胜出”。
来自 CSS.registerProperty()
的自定义属性注册优先于同一个 <custom-property-name> 的任何 @property 规则。
3.1. 语法描述符
名称: | 语法 |
---|---|
适用于: | @property |
值: | <string> |
初始: | 不适用 (见正文) |
指定由 自定义属性注册 表示的 @property 规则的语法, 控制属性值在 计算值 时的解析。
语法 描述符是 @property 规则有效的必需项; 如果缺失,@property 规则无效。
如果提供的字符串不是有效的 语法字符串 (如果在调用 消费语法定义 时返回失败), 则该描述符无效,必须被忽略。
3.2. inherits 描述符
名称: | inherits |
---|---|
适用于: | @property |
值: | true | false |
初始: | n/a(见正文) |
指定由 自定义属性注册 代表的 @property 规则的继承标志,控制属性是否默认继承。
inherits 描述符对于 @property 规则是必需的; 如果缺失,则 @property 规则无效。
3.3. initial-value 描述符
名称: | initial-value |
---|---|
适用于: | @property |
值: | <declaration-value>? |
初始: | 保证无效值(但见正文) |
指定由 自定义属性注册 代表的 @property 规则的初始值,控制属性的 初始值。
如果 syntax 描述符的值为 通用语法定义, 则 initial-value 描述符是可选的。 如果省略,属性的 初始值 是 保证无效值。
否则, 如果 syntax 描述符的值不是 通用语法定义, 则必须满足以下条件,以使 @property 规则有效:
-
必须存在 initial-value 描述符。
-
initial-value 描述符的值必须 根据语法成功解析。
-
initial-value 必须是 计算独立。
如果不满足上述条件,则 @property 规则无效。
4. 在 JS 中注册自定义属性
要通过 JS 注册自定义属性,
CSS
对象扩展了一个 registerProperty()
方法:
dictionary PropertyDefinition {required DOMString name ;DOMString syntax = "*";required boolean inherits ;DOMString initialValue ; };partial namespace CSS {undefined registerProperty (PropertyDefinition ); };
definition
Additional, the Document
object gains a new [[registeredPropertySet]]
private slot,
which is a set of records that describe registered custom properties.
4.1.
registerProperty()
函数
该 registerProperty(PropertyDefinition definition)
方法
根据 definition
中提供的配置选项注册自定义属性。
当调用时,
它执行 注册自定义属性 算法,
将 definition
参数中的选项作为相同名称的参数传递。
-
让 property set 为 当前全局对象的 关联的
Document
的[[registeredPropertySet]]
槽的值。 -
如果 name 不是 自定义属性名称字符串, 抛出
SyntaxError
并退出此算法。如果 property set 已包含 name 作为其属性名称的条目 (按代码点比较), 抛出
InvalidModificationError
并退出此算法。 -
尝试从 syntax 中 消费一个语法定义。 如果返回失败, 抛出
SyntaxError
。 否则,让 syntax definition 为返回的 语法定义。 -
如果 syntax definition 是 通用 语法定义, 且 initialValue 不存在, 让 parsed initial value 为空。 这必须与自定义属性的“默认”初始值相同, 如 [css-variables] 中定义。 跳到算法的下一步。
否则, 如果 syntax definition 是 通用 语法定义, 解析 initialValue 为 <declaration-value>。 如果失败, 抛出
SyntaxError
并退出此算法。 否则, 让 parsed initial value 为解析结果。 跳到算法的下一步。否则,如果 initialValue 不存在, 抛出
SyntaxError
并退出此算法。否则, 解析
initialValue
根据 syntax definition。 如果失败, 抛出SyntaxError
并退出此算法。否则,让 parsed initial value 为解析结果。 如果 parsed initial value 不是 计算独立的, 抛出
SyntaxError
并退出此算法。 -
将 inherit flag 设置为 inherits 的值。
-
让 registered property 为一个 结构体,其属性 名称为 name, 语法为 syntax definition, 初始值为 parsed initial value, 以及继承标志为 inherit flag。 附加 registered property 到 property set。
属性值是 计算独立的,如果它可以仅使用元素上属性的值和不能被 CSS 改变的“全局”信息转换为计算值。
另一方面, 3em 不是 计算独立的, 因为它依赖于元素(或元素父级)的 font-size 的值。 值也不是 var() 函数,因为它依赖于 自定义属性 的值。
当自定义属性使用特定类型注册时, 该属性的指定值如何转换为计算值的过程由所选类型完全定义, 如 § 2.4 计算值时行为 中所述。
注意: 未来可能会添加注销属性的方法。
注册自定义属性不得以任何方式影响 级联。 不管注册属性指定什么语法, 在解析时它仍然被视为普通的 自定义属性, 准许几乎任何内容。 如果 指定值 对于 注册自定义属性 违反注册语法, 则该属性在计算值时变为无效(因此重置为注册的初始值)。
.thing{ --my-color : green; --my-color : url ( "not-a-color" ); color : var ( --my-color); }
是将类为 "thing" 的元素的 color 属性设置为 inherit。 第二个 --my-color 声明在解析时覆盖第一个(两者都是有效的), 而在 color 属性中的 var() 引用被发现为 在计算值时无效(因为 url("not-a-color") 不是颜色)。 在 CSS 管道的这个阶段(计算时间), 唯一可用的后备是属性的初始值, 对于颜色而言是 inherit。 尽管有一个有效可用值(green), 但在解析期间由于被 URL 取代而被移除。
如果我们调用:
CSS. registerProperty({ name: "--my-color" , syntax: "<color>" , initialValue: "black" , inherits: false });
解析并不会显著改变, 无论注册发生在上面的样式表之前还是之后。 唯一的区别是 --my-color 属性变为 在计算值时无效, 并设置为其初始值 black; 然后 color 被 有效地设置为 black, 而不是在计算值时无效并变为 inherit。
4.2.
属性定义 PropertyDefinition
字典
PropertyDefinition
字典表示
作者指定的自定义属性配置选项。 PropertyDefinition
字典包含以下成员:
name
, 类型为 DOMString-
定义的自定义属性的名称。
syntax
, 类型为 DOMString,默认为"*"
-
表示此自定义属性如何解析的字符串。
inherits
, 类型为 boolean-
如果该自定义属性应该沿着 DOM 树继承,则为真;否则为假。
initialValue
, 类型为 DOMString-
此自定义属性的初始值。
5. 语法字符串
语法字符串 描述 注册的自定义属性接受的值类型。语法字符串由 语法组件名称 组成, 可选地 乘以 和 组合。
语法字符串可以解析为 语法定义,其形式为:
-
一组 语法组件,每个组件接受在 § 5.1 支持的名称 中指定的值类型,或
-
通用语法定义 universal syntax definition (*),接受任何有效的标记流。
注意: 无论指定什么语法,所有自定义属性都接受 CSS-wide 关键字,并适当地处理这些值。
"<length>"
-
接受长度值
"<length> | <percentage>"
-
接受长度、百分比、百分比计算表达式和长度计算表达式,但不接受包含长度和百分比值组合的计算表达式。
"<length-percentage>"
-
接受所有
"<length> | <percentage>"
接受的值,以及包含长度和百分比值组合的计算表达式。 "big | bigger | BIGGER"
-
接受标识符
big
、bigger
或BIGGER
。 "<length>+"
-
接受空格分隔的长度值列表。
- "*"
-
接受任何有效的标记流
注意: 语法字符串的内部语法是 CSS 值定义语法 的子集。预计本规范的未来版本将扩展允许的语法的复杂性,使自定义属性更接近 CSS 属性允许的全部内容。
本章的其余部分描述语法字符串的内部语法。
5.1. 支持的名称
本节定义了 支持的语法组件名称,以及生成的 语法组件 所接受的相应类型。
- "<length>"
-
任何有效的 <length> 值
- "<number>"
-
<number> 值
- "<percentage>"
-
任何有效的 <percentage> 值
- "<length-percentage>"
-
任何有效的 <length> 或 <percentage> 值,任何有效的 <calc()> 表达式组合 <length> 和 <percentage> 组件。
- "<color>"
-
任何有效的 <color> 值
- "<image>"
-
任何有效的 <image> 值
- "<url>"
-
任何有效的 <url> 值
- "<integer>"
-
任何有效的 <integer> 值
- "<angle>"
-
任何有效的 <angle> 值
- "<time>"
-
任何有效的 <time> 值
- "<resolution>"
-
任何有效的 <resolution> 值
- "<transform-function>"
-
任何有效的 <transform-function> 值
- "<custom-ident>"
-
任何有效的 <custom-ident> 值
- 任何序列 以标识符开头、可以被视为名称,并与 <custom-ident> 生成匹配
-
该标识符
注意: <custom-ident> 是逐码点比较的; 这与 UA 定义的 CSS 的正常行为不同,后者仅限于 ASCII 并且是 ASCII 不区分大小写。 因此,指定 ident 如
Red
意味着接受精确值 Red; red、RED 及任何其他大小写变体均不匹配。 建议将 idents 限制为 ASCII,并以小写字母书写, 以符合 CSS 约定。 - "<transform-list>"
-
有效的 <transform-function> 值的列表。注意
"<transform-list>"
是等同于"<transform-function>+"
的 预乘数据类型名称
注意: 语法字符串 "*"
将产生
通用语法定义,这不是 语法组件。
因此,"*"
可能不能被 乘以 或 与其他东西结合。
5.2. “+” 和 “#” 乘数
除了 预乘数据类型名称 之外,任何 语法组件名称 后面可以紧跟一个乘数:
- U+002B 加号 (+)
-
表示一个空格分隔的列表。
- U+0023 井号 (#)
-
表示一个逗号分隔的列表。
注意: 乘数必须紧跟在被乘的 语法组件名称 之后出现。
5.3. “|” 组合符
语法字符串 可以使用 U+007C 竖线 (|) 提供多个 语法组件名称。这样的语法字符串将导致生成一个 语法定义 ,其中包含多个 语法 组件。
当一个 语法 定义 具有多个 语法组件 时, 用于解析 CSS 值时,语法组件将按指定顺序匹配。
注意: 即,给定语法字符串
"red | <color>"
,
将匹配值 red
解析为标识符,
而匹配值 blue 将
解析为 <color>。
5.4. 解析语法字符串
5.4.1. 定义
- 数据类型 名称
-
一系列 代码点,由一个 U+003C 小于号 (<) 开头, 后接零个或多个 标识符代码点,并以 U+003E 大于号 (>) 结束。
- 预乘数据类型名称
- 语法 组件
- 语法 组件名称
-
一系列 代码点,它可以是 数据类型名称, 或一个能够产生 <custom-ident> 的序列。
- 语法 定义
-
一个对象,由一系列 语法组件 组成。
- 通用语法定义
-
一个特殊的语法定义,接受任何有效的令牌流。
5.4.2. 消耗语法定义
5.4.3. 消耗语法组件
从 stream 中消耗尽可能多的空格。
让 component 成为一个新的语法组件,其name和multiplier最初为空。
消耗 stream中的下一个输入代码点:
- U+003C LESS-THAN SIGN (<)
-
从 stream 中消耗数据类型名称。 如果返回一个字符串,则将 component 的 name 设置为返回值。 否则,返回失败。
- 标识符开始代码点
- U+005C REVERSE SOLIDUS (\)
-
如果流以标识符序列开头,重新消费当前输入代码点,然后从 stream 中消耗标识符序列, 并将 component 的 name 设置为返回值。 否则返回失败。
如果 component 的 name 未解析为<custom-ident>,返回失败。
- 其他任何情况
-
返回失败。
如果 component 的 name 是预乘数据类型名称, 返回 component。
如果 stream中的下一个输入代码点为U+002B PLUS SIGN (+)或U+0023 NUMBER SIGN (#), 消耗下一个输入代码点, 并将 component 的 multiplier 设置为当前输入代码点。
返回 component。
5.4.4. 消耗数据类型名称
注意:此算法假设已经从流中消耗了一个 U+003C LESS-THAN SIGN (<) 代码点。
让 name 最初为一个包含单个 U+003C LESS-THAN SIGN (<) 代码点的字符串。
重复消耗下一个输入代码点:
6. CSSOM
[[registeredPropertySet]]
插槽和 Document
,
并将所有自定义属性视为未注册。6.1.
CSS CSSPropertyRule
接口
CSSPropertyRule
接口表示一个@property 规则。
[Exposed =Window ]interface CSSPropertyRule :CSSRule {readonly attribute CSSOMString name ;readonly attribute CSSOMString syntax ;readonly attribute boolean inherits ;readonly attribute CSSOMString ?initialValue ; };
name
, 类型为 CSSOMString, 只读- 与@property规则相关的自定义属性名称。
syntax
, 类型为 CSSOMString, 只读- 与@property相关的语法,完全按照指定内容。
inherits
, 类型为 boolean, 只读- 与@property规则相关的继承描述符。
initialValue
, 类型为 CSSOMString, 只读,可能为空- 与@property规则相关的初始值,可能不存在。
-
字符串
"@property"
后跟一个空格(U+0020)。 -
对规则名称执行序列化标识符的结果,后跟一个空格(U+0020)。
-
字符串
"{ "
,即一个左大括号(U+007B),后跟一个空格(U+0020)。 -
字符串
"syntax:"
,后跟一个空格(U+0020)。 -
字符串
"inherits:"
,后跟一个空格(U+0020)。 -
对于规则的inherits属性,根据属性值的不同,以下任意一种:
- true
-
字符串
"true"
后跟一个分号(U+003B),后跟一个空格(U+0020)。 - false
-
字符串
"false"
后跟一个分号(U+003B),后跟一个空格(U+0020)。
-
如果规则的initial-value存在,则执行以下子步骤:
-
字符串
"initial-value:"
。 -
对规则的initial-value执行序列化CSS值,后跟一个分号(U+003B),后跟一个空格(U+0020)。
-
-
一个右大括号(U+007D)。
6.2.
CSSStyleValue
具体化
对于指定值,具体化一组组件值并返回结果。
对于计算值:
-
如果值是<length>、<integer>、<number>、<angle>、<time>、<resolution>、<percentage>或<length-percentage>;具体化一个数值并返回结果。
-
如果值是<transform-list>,具体化一个<transform-list>并返回结果。
-
如果值是一个<image>,具体化一个CSSImageValue并返回结果。
-
否则,作为CSSStyleValue具体化,其中
[[associatedProperty]]
内部槽设置为property,并返回结果。
7. 示例
7.1. 示例 1: 使用自定义属性添加动画行为
< script > CSS. registerProperty({ name: "--stop-color" , syntax: "<color>" , inherits: false , initialValue: "rgba(0,0,0,0)" }); </ script > < style > . button { --stop-color : red ; background : linear-gradient( var ( --stop-color ), black ); transition : -- stop-color 1 s ; } . button : hover { --stop-color : green ; } </ style >
7.2. 示例 2: 使用 @property 注册属性
< script > CSS. paintWorklet. addModule( 'circle.js' ); </ script > < style > @ property --radius { syntax : "<length>" ; inherits : false ; initial-value : 0px ; } div { width : 100 px ; height : 100 px ; --radius : 10 px ; background : paint ( circle ); transition : -- radius 1 s ; } div : hover { --radius : 50 px ; } </ style > < div ></ div >
// circle.js registerPaint( 'circle' , class { static get inputProperties() { return [ '--radius' ]; } paint( ctx, geom, properties) { let radius= properties. get( '--radius' ). value; ctx. fillStyle= 'black' ; ctx. beginPath(); ctx. arc( geom. width/ 2 , geom. height/ 2 , radius, 0 , 2 * Math. PI); ctx. fill(); } });
8. 安全考虑
这些特性没有已知的安全问题。
9. 隐私考虑
这些特性没有已知的隐私问题。
10. 变更
10.1. 自2020年10月13日的工作草案以来的变更
/* 到2024年3月20日 */