1. 简介
每个 CSS 属性的值定义字段可以包含关键字、数据类型(显示在 < 和 > 之间)以及关于它们如何组合的信息。此规范描述了许多属性通用的通用数据类型(<length> 是最广泛使用的),而更具体的数据类型(例如 <spacing-limit>)则在相应的模块中描述。
1.1. 模块交互
此模块替换并扩展了 [CSS2] 第 1.4.2.1、4.3 和 A.2 节中的数据类型定义。
2. 值定义语法
此处描述的 值定义语法 用于定义 CSS 属性的有效值集(以及 CSS 许多其他部分的有效语法)。这样描述的值可以有一个或多个组件。
2.1. 组件值类型
组件值类型通过多种方式指定
-
基本数据类型,出现在 < 和 > 之间(例如 <length>, <percentage> 等)。对于 数值数据类型,此类型表示法可以使用下面描述的 括号范围表示法 对任何范围限制进行标注。
-
属性值范围,代表与同名属性相同的模式。这些写成属性名称,用单引号括起来,位于 < 和 > 之间,例如 <'border-width'>, <'background-attachment'> 等。
这些类型不包括 CSS 全局关键字(如 inherit)。此外,如果属性的值语法是 逗号分隔的重复,则对应的类型不包含顶层 逗号分隔列表乘数。(例如,如果名为 pairing 的属性定义为 [ <custom-ident> <integer>? ]#,则 <'pairing'> 等价于 [ <custom-ident> <integer>? ],而不是 [ <custom-ident> <integer>? ]#。)
为什么要移除乘数?
之所以从这些值类型中剔除顶层乘数,是因为顶层逗号分隔的重复主要用于 协调列表属性,当简写属性组合几个此类属性时,它需要非乘法语法,以便能够构造自身的逗号分隔重复。
如果没有这种特殊处理,每个此类长写属性都必须定义一个专门针对内部值的临时生成规则,这会使语法总体上更难理解。
-
函数式符号及其参数。这些写成函数名称,后跟一对空括号,位于 < 和 > 之间,例如 <calc()>,并引用相应名称的 函数式符号。
-
其他非终结符。这些写成非终结符的名称,位于 < 和 > 之间,如 <spacing-limit>。注意 <border-width> 和 <'border-width'> 之间的区别:后者代表 border-width 属性的语法,前者需要显式展开。非终结符的定义通常位于规范中其首次出现的地方附近。
一些属性值定义也包含斜杠(/)、逗号(,)和/或括号作为字面量。这些代表其对应的标记。出现在组件值中的其他非关键字字面字符,如“+”,必须用单引号括起来。
语法中指定的逗号 在某些情况下是隐式可省略的,即当用于分隔语法中的可选项时。在属性或其他 CSS 值中的顶层列表内,或函数的参数列表中,如果满足以下情况,必须省略语法中指定的逗号:
- 逗号前的所有项已被省略
- 逗号后的所有项已被省略
- 由于逗号之间的项被省略,导致多个逗号相邻(忽略 空白符/注释)。
example ( first?, second?, third?)
给定此语法,书写 example(first, second, third) 是有效的,example(first, second)、example(first, third) 或 example(second) 也是如此。然而,example(first, , third) 是无效的,因为其中一个逗号不再分隔两个选项;类似地,example(,second) 和 example(first,) 是无效的。example(first second) 也是无效的,因为仍然需要逗号来实际分隔选项。
如果逗号不能隐式省略,语法必须变得复杂得多,才能正确表达参数可以被省略的方式,从而极大地掩盖了该功能的简洁性。
所有 CSS 属性也接受 CSS 全局关键字值作为其属性值的唯一组件。为了可读性,这些并未在属性值语法定义中显式列出。例如,border-color 在 CSS 层叠与继承第 3 级下的完整值定义是 <color>(即使它被列为 <color>)。
注意: 这意味着,通常情况下,将这些关键字与同一声明中的其他组件值组合会导致无效声明。例如,background: url(corner.png) no-repeat, inherit; 是无效的。
2.2. 组件值组合符
组件值可以按照以下方式排列为属性值:
- 并置组件意味着所有组件必须按给定顺序出现。
- 双与号(&&)分隔两个或多个组件,所有组件都必须出现,且顺序不限。
- 双竖线(||)分隔两个或多个选项:必须出现一个或多个,且顺序不限。
- 竖线(|)分隔两个或多个备选项:必须恰好出现其中一个。
- 方括号 ([ ]) 用于分组。
相邻排列的优先级高于双与号,双与号高于双竖线,双竖线高于单竖线。因此,下列语句是等价的:
a b | c || d && e f[ a b] |[ c ||[ d &&[ e f]]]
对于可重排序组合符(||, &&),语法的顺序无关紧要:同一分组中的组件可以以任何顺序交错。因此,以下行是等价的:
a || b || c b || a || c
注意: 组合符不是结合性的,因此分组很重要。例如,a || b || c 和 a || [ b || c ] 是不同的语法:前者允许像 b a c 这样的值,但后者不允许。
2.3. 组件值乘数
每种类型、关键字或括号组后面都可以跟随以下修饰符之一:
- 星号(*)表示前面的类型、单词或组出现零次或多次。
- 加号(+)表示前面的类型、单词或组出现一次或多次。
- 问号(?)表示前面的类型、单词或组是可选的(出现零次或一次)。
- 花括号中的单个数字({A})表示前面的类型、单词或组出现 A 次。
- 花括号中的逗号分隔数字对({A,B})表示前面的类型、单词或组至少出现 A 次,至多出现 B 次。B 可以省略({A,})以表示必须至少有 A 次重复,且重复次数没有上限。
- 井号(#)表示前面的类型、单词或组出现一次或多次,并由逗号标记(可以可选地被 空白符和/或注释包围)分隔。它后面可以可选地跟上面的花括号形式,以精确指示重复发生的次数,如 <length>#{1,4}。
- 组后的感叹号(!)表示该组是必需的,并且必须产生至少一个值;即使组内项的语法允许省略整个内容,也必须至少保留一个组件值。
+ 和 # 乘数可以堆叠为 +#;同样,# 和 ? 乘数可以堆叠为 #?。这些堆叠中的每一个都表示将后面的乘数应用于前面的乘数的结果。(这些相同的堆叠可以使用分组来表示,但在复杂语法中,这会使括号数量超出可读范围。)
对于重复的组件值(由 *, + 或 # 表示),UA 必须支持至少 20 次重复。如果属性值包含的重复次数超过支持的数量,则该声明必须被忽略,就像它是无效的一样。
2.4. 组合符与乘数模式
有一小套常见的组合多个独立 组件值 的方法,以特定的数量和顺序出现。特别是,通常需要表达作者必须从一组组件值中选择零个或多个、一个或多个、或者全部,并且以语法中指定的顺序或以任何顺序进行选择。
| 按顺序 | 任何顺序 | |
|---|---|---|
| 零个或多个 | A? B? C?
| A? || B? || C?
|
| 一个或多个 |
| A || B || C
|
| all | A B C
| A && B && C
|
注意,“任何顺序”的可能性都是使用组合符表达的,而“按顺序”的可能性都是并置的变体。
2.5. 组件值与空白符
除非另有说明,空白符和/或注释可以出现在使用上述 组合符 和 乘数 组合的组件之前、之后和/或之间。
注意: 在许多情况下,组件之间确实需要空格,以便将它们彼此区分开来。例如,值 1em2em 将被解析为单个 <dimension-token>,数字为 1,标识符为 em2em,这是一个无效的单位。在这种情况下,2 之前需要一个空格,才能将其解析为两个长度 1em 和 2em。
2.6. 属性值示例
以下是一些属性及其对应的值定义字段示例:
| 属性 | 值定义字段 | 示例值 |
|---|---|---|
| orphans (孀行) | <integer>(整数) | 3 |
| text-align | left | right | center | justify | center |
| padding-top | <length> | <percentage> | 5% |
| outline-color | <color> | invert | #fefefe |
| text-decoration | none | underline || overline || line-through || blink | overline underline |
| font-family | [ <family-name> | <generic-family> ]# | "Gill Sans", Futura, sans-serif |
| border-width | [ <length> | thick | medium | thin ]{1,4} | 2px medium 4px |
| box-shadow | [ inset? && <length>{2,4} && <color>? ]# | none | 3px 3px rgba(50%, 50%, 50%, 50%), lemonchiffon 0 0 4px inset |
3. 文本数据类型
文本数据类型 包括各种关键字和标识符,以及字符串(<string>)和 URL(<url>)。
CSS 标识符(通用记为 <ident>)由符合 <ident-token> 语法的字符序列组成。[CSS-SYNTAX-3] 标识符不能加引号;否则它们会被解释为字符串。CSS 属性接受两类 标识符:预定义关键字 和 作者定义标识符。
注意: <ident> 生成规则并非用于属性值定义,而应使用 <custom-ident>。提供它是为了方便定义其他语法结构。
3.1. 预定义关键字
在值定义字段中,具有预定义含义的 关键字 字面出现。关键字是 标识符,并按 ASCII 大小写不敏感 方式进行解释(即 [a-z] 和 [A-Z] 是等价的)。
Value : collapse | separate
这里是它的用法示例:
table{ border-collapse : separate}
3.1.1. CSS 全局关键字:initial, inherit 和 unset
如上文定义,所有属性都接受 CSS 全局关键字,它们代表所有 CSS 属性共有的值计算。这些关键字在 CSS 层叠与继承模块 中被规范定义。
其他 CSS 规范可以定义额外的 CSS 全局关键字。
3.2. 作者定义标识符:<custom-ident> 类型
某些属性接受任意作者定义的标识符作为组件值。此通用数据类型记为 <custom-ident>,表示任何不会在该属性的值定义中被误解为预定义关键字的有效 CSS 标识符。此类标识符完全区分大小写,即使在 ASCII 范围内也是如此(例如 example 和 EXAMPLE 是两个不同且无关的用户定义标识符)。
CSS 全局关键字不是有效的 <custom-ident>。 default 关键字被保留,也不是有效的 <custom-ident>。使用 <custom-ident> 的规范必须清楚地说明有哪些其他关键字从 <custom-ident> 中排除(如果有的话)——例如,通过声明该属性值定义中的任何预定义关键字都被排除在外。排除的关键字在所有 ASCII 大小写排列 中均被排除。
在解析属性值中位置模糊的关键字时,<custom-ident> 生成规则只有在没有其他未满足的生成规则可以声明该关键字时,才能声明它。
注意: 当设计包含 <custom-ident> 的语法时,<custom-ident> 应该始终是“位置明确的”,这样它就不可能与属性中的任何关键字值发生冲突。
3.3. 引号字符串:<string> 类型
字符串由 <string> 表示。当字面书写时,它们由双引号或单引号定界的字符序列组成,对应于 CSS 语法模块 中的 <string-token> 生成规则 [CSS-SYNTAX-3]。
"\" " 或 "\22" )。单引号类似('\' ' 或 '\27' )。content : "this is a 'string'." ; content : "this is a \" string\"." ; content : 'this is a "string".' ; content : 'this is a \' string\'.'
出于美观或其他原因,可以将字符串跨多行书写,但在这种情况下,换行符本身必须用反斜杠(\)转义。随后换行符会从字符串中移除。例如,以下两个选择器是完全相同的:
由于字符串不能直接表示换行符,要在字符串中包含换行符,请使用转义符 "\A"。(十六进制 A 是 Unicode 中的换行字符(U+000A),但在 CSS 中代表“换行符”的通用概念。)
3.4. 资源定位符:<url> 类型
url() 函数式符号,记为 <url>,表示一个 URL,即指向资源的指针。<url> 的典型语法是:
<url> =url ( <string> <url-modifier> * )
url() 也可以不带引号书写,在这种情况下,它被 特殊解析 为 <url-token>;参见 CSS 语法 3 § 4.3.6 消费 URL 标记。[CSS-SYNTAX-3]
background : url ( "http://www.example.com/pinkish.gif" ); background : url ( http://www.example.com/pinkish.gif );
注意: 不带引号的 url() 语法不能接受 <url-modifier> 参数,并且有额外的转义要求:URL 中出现的圆括号、空白符、单引号 (') 和双引号 (") 必须用反斜杠转义,例如 url(open\(parens), url(close\)parens)。(在带引号的 <string> url() 中,只需转义换行符和用于引号的字符。)根据 URL 的类型,也可能将这些字符写为 URL 转义符(例如 url(open%28parens) 或 url(close%29parens)),如 [URL] 中所述。
某些 CSS 上下文(如 @import)也允许将 <url> 表示为裸 <string>,而无需函数包装。在这种情况下,该字符串的行为与包含该字符串的 url() 函数完全相同。
3.4.1. 相对 URL
为了创建不依赖于资源绝对位置的模块化样式表,作者应使用相对 URL。相对 URL(如 [URL] 中定义)使用基 URL 解析为完整 URL。RFC 3986 第 3 节定义了此过程的规范算法。对于 CSS 样式表,基 URL 是样式表本身的基 URL,而不是已样式化源文档的基 URL。嵌入文档中的样式表具有与容器关联的基 URL。
注意: 对于 HTML 文档,基 URL 是可变的。
当 <url> 出现在属性的计算值中时,它会解析为绝对 URL,如上一段所述。UA 无法解析为绝对 URL 的 URL 的计算值即为指定值。
body{ background : url ( "tile.png" ) }
位于 URL 指定的样式表中:
http : //www.example.org/style/basic.css
源文档的 <body> 的背景将用 URL 指定的资源所描述的图像进行平铺:
http : //www.example.org/style/tile.png
无论包含 <body> 的源文档的 URL 如何,都将使用相同的图像。
3.4.1.1. 片段 URL
为了解决浏览器 URL 处理中的一些常见怪癖,CSS 对仅包含片段的 URL 有特殊行为。
如果 url() 的值以 U+0023 NUMBER SIGN(#)字符开头,则按 URL 的正常方式解析它,但额外设置 url() 的 本地 URL 标志。
当匹配设置了 本地 URL 标志 的 url() 时,忽略除 URL 片段之外的所有内容,并针对解析相对 URL 的当前文档解析该片段。此引用必须始终被视为同文档引用(而不是跨文档引用)。
在 序列化 设置了 本地 URL 标志 的 url() 时,它必须仅序列化为片段。
什么是“浏览器怪癖”?
理论上,每当文档的基 URL 发生变化(例如通过修改 base 元素或调用 pushState())时,浏览器都应该重新解析任何相对 URL(包括仅包含片段的 URL)。然而在很多情况下它们并没有这样做,因此如果没有特殊处理,仅片段的 URL 会突然变成跨文档引用(指向之前的基 URL),并在其使用的许多地方失效。
由于仅片段的 URL 表达了一种明确的语义,即无论当前 URL 是什么,都希望引用当前文档,因此这种 Hack 至少在这些情况下保留了预期的行为。
3.4.2. 空 URL
如果 <url> 的值是空字符串(如 url("") 或 url()),则 URL 必须解析为无效资源(类似于 URL about:invalid 的作用)。
它的计算值是 url(""),并且必须按此序列化。
注意: 这与 Web 平台其他地方嵌入资源的空 URL 行为相匹配,并避免了因编辑错误导致 url() 值为空而重新请求样式表或宿主文档造成过多的流量,这几乎肯定会是 url() 出现的任何地方的无效资源。Web 平台上的链接确实允许空 URL,因此如果/当 CSS 获得一些控制超链接的功能时,这种限制可以在这些上下文中放宽。
3.4.3. URL 修饰符
url() 函数支持指定额外的 <url-modifier>,它们以某种方式改变 URL 的含义或解释。 <url-modifier> 要么是 <ident>,要么是 函数式符号。
本规范未定义任何 <url-modifier>,但其他规范可能会这样做。
注意: 既不带引号也不包装在 url() 符号中的 <url> 不能接受任何 <url-modifier>。
4. 数值数据类型
数值数据类型用于表示数量、索引、位置和其他此类值。尽管在给定的数值中表示数量(数值方面)时可能存在许多语法变体,但 指定值 和 计算值 并不区分这些变体:它们代表值的抽象数量,而不是其语法表示。
数值数据类型 包括 <integer>, <number>, <percentage> 以及各种 维度,包括 <length>, <angle>, <time>, <frequency> 和 <resolution>。
注意: 虽然此处定义了通用 维度,但其他一些模块定义了额外的数据类型(例如 [css-grid-1] 引入了 fr 单位),其使用更加局部化。
4.1. 范围限制与范围定义表示法
属性可以将数值限制在某个范围内。如果值在允许范围之外,除非另有说明,否则该声明无效且必须 忽略。可以使用 CSS 括号范围表示法————在数值类型表示法中对范围限制进行标注,出现在尖括号内,标识关键字之后,表示 min 和 max 之间的闭区间(包含边界)。例如,<integer [0,10]> 表示 0 到 10 之间的整数(含边界),而 <angle [0,180deg]> 表示 0deg 到 180deg 之间的角度(以任何单位表示)。
注意: CSS 值通常不允许开区间;因此仅使用方括号表示法。
CSS 理论上支持所有值类型的无限精度和无限范围;但在现实中,实现的容量是有限的。 UA 应支持足够有用的范围和精度。理想情况下无限的范围极值应根据情况分别使用 ∞ 或 −∞ 指示。例如,<length [0,∞]> 表示非负长度。
如果未通过 括号范围表示法 或属性描述指示任何范围,则假设范围为 。
−∞ 或 ∞ 的值必须不带单位书写,即使该值类型使用单位。0 值可以不带单位书写,即使该值类型不允许“无单位的零”(如 <time>)。
注意: 在撰写本文时,括号范围表示法 是新的;因此在大多数 CSS 规范中,任何范围限制仅在正文中描述。(例如,“不允许负值”或“负值无效”表示 范围。)这不会使它们失去约束力。
4.2. 整数:<integer> 类型
整数值记为 <integer>。
当字面书写时,整数 是一个或多个十进制数字 0 到 9,对应于 CSS 语法模块中 <number-token> 生成规则的子集 [CSS-SYNTAX-3]。整数的第一位数字前可以紧跟 - 或 + 以指示整数的符号。
4.3. 实数:<number> 类型
数值记为 <number>,代表实数,可能带有小数部分。
当字面书写时,数字 是一个 整数,或者零个或多个十进制数字后跟点(.)后再跟一个或多个十进制数字;可选地,它可以以字母“e”或“E”结尾,后跟一个整数,表示 科学记数法 中的十进制指数。它对应于 CSS 语法模块 中的 <number-token> 生成规则 [CSS-SYNTAX-3]。与整数一样,数字的第一个字符前可以紧跟 - 或 + 以指示数字的符号。
4.4. 带单位的数字:维度 (dimension) 值
通用术语 维度 指的是一个带有附加单位的数字,记为 <dimension>。
当字面书写时,维度 是一个 数字,紧随其后的是单位标识符,即一个 标识符。它对应于 CSS 语法模块 中的 <dimension-token> 生成规则 [CSS-SYNTAX-3]。与关键字一样,单位标识符是 ASCII 大小写不敏感 的。
CSS 使用 <dimension> 指定距离(<length>)、时长(<time>)、频率(<frequency>)、分辨率(<resolution>)和其他量。
4.4.1. 兼容单位
在 序列化 计算值 [CSSOM] 时,兼容单位(通过静态乘法因子相关的单位,如 px 和 in 之间的 96:1 因子,或 em 和 px 之间计算出的 font-size 因子)被转换为单个 规范单位。每组兼容单位定义了其中哪一个是将用于序列化的 规范单位。
在序列化作为 使用值 的已解析值时,所有表示长度的值类型(百分比、数字、关键字等)都被视为与长度 兼容。同样,任何返回 使用值 的未来 API 必须将任何表示距离/时长/频率等的值视为与相关的 维度 类 兼容,并相应地规范化。
4.5. 百分比:<percentage> 类型
百分比值记为 <percentage>,表示某个参考值的几分之一。
当字面书写时,百分比 由一个 数字 紧跟百分号 % 组成。它对应于 CSS 语法模块 中的 <percentage-token> 生成规则 [CSS-SYNTAX-3]。
百分比值始终相对于另一个量,例如长度。允许百分比的每个属性也定义了百分比所引用的量。此量可以是同一元素的另一个属性的值、祖先元素的属性值、格式化上下文的度量(例如,包含块的宽度),或其他内容。
4.6. 百分比与维度的混合
在 <percentage> 可以表示与同一 组件值 位置中的 维度 相同的数量,并因此可以在 calc() 表达式中与它们组合的情况下,可以在属性语法中使用以下便捷表示法:
- <length-percentage>
-
等价于
,其中 <percentage> 将解析为 <length>。[ <length> | <percentage>] - <frequency-percentage>
-
等价于
,其中 <percentage> 将解析为 <frequency>。[ <frequency> | <percentage>] - <angle-percentage>
-
等价于
,其中 <percentage> 将解析为 <angle>。[ <angle> | <percentage>] - <time-percentage>
-
等价于
,其中 <percentage> 将解析为 <time>。[ <time> | <percentage>]
另一方面,hsl() 函数的第二个和第三个参数只能表示为 <percentage>。尽管它们的位置允许 calc() 生成规则,但它们只能将百分比与自身组合,如 calc(10% + 20%)。
注意: 规范不应在语法中交替使用 <percentage> 代替维度,除非它们是 兼容 的。
注意: 将来可以根据需要添加更多的 <type-percentage> 生成规则。永远不会添加 <number-percentage>,因为 <number> 和 <percentage> 不能在 calc() 中组合。
5. 距离单位:<length> 类型
长度是指距离测量,在属性定义中记为 <length>。长度是一个 维度。
对于零长度,单位标识符是可选的(即可以在语法上表示为 <number> 0)。但是,如果属性中 0 可以被解析为 <number> 或 <length>(例如 line-height),它必须解析为 <number>。
属性可以将长度值限制在一定范围内。如果值在允许范围之外,则该声明无效且必须 忽略。
虽然某些属性允许负长度值,但这可能会使格式化复杂化,并且可能存在特定于实现的限制。如果允许使用负长度值但无法支持,则必须将其转换为可以支持的最接近的值。
如果无法支持 使用 长度,用户代理必须在 实际 值中进行近似处理。
5.1. 相对长度
相对长度单位 指定相对于另一个长度的长度。使用相对单位的样式表可以更容易地从一种输出环境扩展到另一种环境。
相对单位包括:
| unit | 相对于 |
|---|---|
| em | 元素的字体大小 |
| ex | 元素字体的 x-height |
| ch | 元素字体中“0”(ZERO,U+0030)字形的 字形度量 (advance measure) |
| 取余 (rem) | 根元素的字体大小 |
| vw | 视口宽度的 1% |
| vh | 视口高度的 1% |
| vmin | 视口较小维度的 1% |
| vmax | 视口较大维度的 1% |
子元素不会继承为其父元素指定的相对值;它们继承的是 计算值。
5.1.1. 字体相对长度:em, ex, ch, rem 单位
字体相对长度 是指使用它们的元素的字体度量——或者在 rem 的情况下,指根元素的度量。
- em
- 等于使用该单位的元素的 font-size 属性的计算值。
- 取余 (rem)
- 等于根元素上 em 单位的计算值。
- ex 单位
- 等于 首次可用字体 的使用 x-height [CSS3-FONTS]。之所以称为 x-height,是因为它通常等于小写字母“x”的高度。但是,即使对于不包含“x”的字体,也会定义 ex。字体的 x-height 可以通过多种方式找到。有些字体包含可靠的 x-height 度量。如果不可用可靠的字体度量,UA 可以从一个小写字形的高度确定 x-height。一种可能的启发式方法是观察小写字母“o”的字形延伸到基线下方多远,并将该值从其边界框的顶部减去。在无法或不切实际确定 x-height 的情况下,必须假设其值为 0.5em。
- ch 单位
- 代表欧洲字母数字字符的典型 字形度量 (advance measure),并测量为用于渲染它的字体中“0”(ZERO,U+0030)字形的已使用 字形度量。(字形的 字形度量 是其前进宽度或高度,以元素内联轴上的那个为准。)
注意: 此测量是单个窄字形的 字形度量 的近似值(在等宽字体中为精确测量),从而允许基于预期的字形数量进行测量。
注意: 字形的字形度量取决于书写模式和文本方向,以及字体设置、文本转换以及任何其他影响字形选择或方向的属性。
在无法或不切实际确定“0”字形的度量的情况下,必须假设其宽度为 0.5em,高度为 1em。因此,在一般情况下 ch 单位回落到 0.5em,而在其被直排版时(即 writing-mode 为 vertical-rl 或 vertical-lr 且 text-orientation 为 upright)回落到 1em)。
当在元素上下文之外使用时(例如在 媒体查询 中),这些单位指的是对应于 font 属性初始值的计算字体度量。当在元素的 font-size 属性值中使用时,这些单位指的是父元素的计算字体度量(如果元素没有父元素,则为对应于 font 属性初始值的计算字体度量)。
字体相对长度是在没有整形 (shaping) 的情况下计算的。
5.1.2. 视口百分比长度:vw, vh, vmin, vmax 单位
视口百分比长度 相对于 初始包含块 的大小——其自身基于视口(对于 连续媒体)或 页面区域(对于 分页媒体)的大小。当初始包含块的高度或宽度改变时,它们会相应地缩放。然而,假设不存在滚动条。
对于 分页媒体,视口百分比长度的确切定义推迟到 [CSS3PAGE]。
- vw 单位
- 等于初始包含块宽度的 1%。
- vh 单位
- 等于初始包含块高度的 1%。
- vmin 单位
- 等于 vw 或 vh 中的较小者。
- vmax 单位
- 等于 vw 或 vh 中的较大者。
5.2. 绝对长度:cm, mm, Q, in, pt, pc, px 单位
绝对长度单位 彼此之间是固定的,并 锚定 到某些物理度量。它们主要在已知输出环境时有用。绝对单位包括 物理单位(in, cm, mm, pt, pc, Q)和 视觉角度单位(像素单位)(px)
| unit | name | 等价性 |
|---|---|---|
| cm(厘米) | 厘米 | 1cm = 96px/2.54 |
| mm(毫米) | 毫米 | 1mm = 1cm 的 1/10 |
| 变量 A | 四分之一毫米 | 1Q = 1cm 的 1/40 |
| 属于 (in) | 英寸 | 1in = 2.54cm = 96px |
| pc(派卡) | 派卡 (picas) | 1pc = 1in 的 1/6 |
| pt(磅) | points | 1pt = 1in 的 1/72 |
| px(像素) | 像素 (pixels) | 1px = 1in 的 1/96 |
h1{ margin : 0.5 in } /* inches */ h2{ line-height : 3 cm } /* centimeters */ h3{ word-spacing : 4 mm } /* millimeters */ h3{ letter-spacing : 1 Q } /* quarter-millimeters */ h4{ font-size : 12 pt } /* points */ h4{ font-size : 1 pc } /* picas */ p{ font-size : 12 px } /* px */
注意: 出版上下文中的长度有时写为 ,表示长度为 2 派卡和 3 点。这些可以在 CSS 中写为 calc(2pc + 3pt)(见 § 8.1 数学表达式:calc())。
所有的绝对长度单位都是 兼容 的,并且 px 是它们的 规范单位。
对于 CSS 设备,这些维度 锚定 的方式要么是:
对于打印媒体在典型的观看距离下,锚定单位(anchor unit)应为物理单位(英寸、厘米等)。对于屏幕媒体(包括高分辨率设备)、低分辨率设备以及观看距离特殊的设备,建议改用像素单位(pixel unit)作为锚定单位。对于此类设备,建议像素单位指代最接近参考像素(reference pixel)的整数个设备像素。
注意:如果锚定单位是像素单位,则物理单位可能与其实际物理测量值不符。反之,如果锚定单位是物理单位,则像素单位可能无法映射为整数个设备像素。
注意:此处对像素单位和物理单位的定义与 CSS1 和 CSS2 的早期版本不同。特别是在之前的 CSS 版本中,像素单位和物理单位之间并非通过固定比例关联:物理单位始终与其物理测量值绑定,而像素单位则会发生变化以最接近参考像素。(做出这一不幸的修改是因为太多的现有内容依赖于 96dpi 的假设,破坏这一假设会导致这些内容失效。)
注意:单位是不区分 ASCII 大小写的,序列化为小写,例如 1Q 序列化为 1q。
参考像素(reference pixel)是指在设备像素密度为 96dpi 且距离读者一臂之长的情况下,一个像素的视角。对于 28 英寸的标准臂长,视角约为 0.0213 度。因此,在臂长距离阅读时,1px 对应约 0.26 毫米(1/96 英寸)。
下图说明了观看距离对参考像素大小的影响:71 厘米(28 英寸)的阅读距离导致参考像素为 0.26 毫米,而 3.5 米(12 英尺)的阅读距离导致参考像素为 1.3 毫米。
第二张图说明了设备分辨率对像素单位的影响:在低分辨率设备(例如典型的计算机显示器)上,1px 乘 1px 的区域被单个点覆盖,而在更高分辨率的设备(例如打印机)上,相同的区域被 16 个点覆盖。
设备像素(device pixel)是设备输出端能够显示其全范围色彩的最小面积单位。对于典型的彩色屏幕,它是一个包含红、绿、蓝子像素的正方形或略带长方形的区域。存在许多非传统输出设备可以模糊这一定义,例如以更高分辨率显示某些颜色。然而,此类设备仍会暴露某种等效的“设备像素”概念。
6. 其他量
6.1. 角度单位:<angle> 类型及 deg、grad、rad、turn 单位
角度值是标记为 <angle> 的 <dimension>(维度)。角度单位标识符为
- 度(deg)
- 度。一个完整的圆有 360 度。
- grad
- 梯度(Gradians),也称为“gons”或“grades”。一个完整的圆有 400 个梯度。
- rad
- 弧度。一个完整的圆有 2π 弧度。
- turn
- 转。一个完整的圆有 1 转。
例如,直角为 90deg 或 100grad 或 0.25turn 或约 1.57rad。
所有 <angle> 单位都是兼容的,其中 deg 是它们的规范单位。
例如,在 linear-gradient() 函数中,确定渐变方向的 <angle> 被解释为方位角。
注意:出于遗留原因,<angle> 的某些用法允许直接使用 0 来表示 0deg。然而,这并不是普遍适用的,且在 <angle> 类型的未来用法中将不会出现。
6.2. 时长单位:<time> 类型及 s、ms 单位
时间值是标记为 <time> 的 维度。时间单位标识符为
- s
- 秒。
- ms
- 毫秒。一秒有 1000 毫秒。
所有 <time> 单位都是兼容的,其中 s 是它们的规范单位。
属性可能会将时间值限制在一定范围内。如果该值超出允许范围,则该声明无效且必须被忽略。
6.3. 频率单位:<frequency> 类型及 Hz、kHz 单位
频率值是标记为 <frequency> 的 维度。频率单位标识符为
- Hz
- 赫兹。它表示每秒发生的次数。
- kHz
- 千赫兹。一千赫兹等于 1000 赫兹。
例如,在表示声音音调时,200Hz(或 200hz)是低音,而 6kHz(或 6khz)是高音。
所有 <frequency> 单位都是兼容的,其中 hz 是它们的规范单位。
注意:单位是不区分 ASCII 大小写的,序列化为小写,例如 1Hz 序列化为 1hz。
6.4. 分辨率单位:<resolution> 类型及 dpi、dpcm、dppx 单位
分辨率单位是标记为 <resolution> 的 维度。分辨率单位标识符为
- dpi
- 每英寸点数。
- dpcm
- 每厘米点数。
- dppx
- 每个 px 单位的点数。
<resolution> 单位通过指出多少个此类“点”适合 CSS 的 in、cm 或 px,来表示图形表示中单个“点”的大小。关于其用法,请参见 [MEDIAQ] 中的 resolution 媒体查询,或 [CSS3-IMAGES] 中定义的 image-resolution 属性。
所有 <resolution> 单位都是兼容的,且 dppx 是它们的规范单位。
<resolution> 值的允许范围始终不包括负值,此外还包括可能指定的任何明确范围。
请注意,由于 CSS in 到 CSS px 1:96 的固定比例,1dppx 等同于 96dpi。这对应于 CSS 中显示的图像的默认分辨率:参见 image-resolution。
@media ( min-resolution:2 dppx ) { ...}
7. 其他地方定义的数据类型
某些数据类型是在它们自己的模块中定义的。此示例讨论了一些在多个规范中通用的数据类型。
7.1. 颜色:<color> 类型
<color> 数据类型定义在 [CSS3COLOR] 中。支持 CSS Color Level 3 或其后续版本的用户代理(UA)必须按照其中定义来解释 <color>。
7.2. 图像:<image> 类型
<image> 数据类型定义在 [CSS3-IMAGES] 中。支持 CSS Images Level 3 或其后续版本的用户代理必须按照其中定义来解释 <image>。尚未支持 CSS Images Level 3 的用户代理必须将 <image> 解释为 <url>。
7.3. 二维定位:<position> 类型
<position> 值指定对象区域(例如背景图像)在定位区域(例如背景定位区域)内的位置。它的计算和解释方式与 background-position 的指定方式相同。[CSS3-BACKGROUND]
<position> =[ [ left | center | right | top | bottom | <length-percentage>] |[ left | center | right] &&[ top | center | bottom] |[ left | center | right | <length-percentage>] [ top | center | bottom | <length-percentage>] |[ [ left | right] <length-percentage>] &&[ [ top | bottom] <length-percentage>] ]
注意:background-position 属性也接受三值语法。此语法已被通用地禁止,因为它在与属性值中的其他长度或百分比组件结合使用时会产生解析歧义。
序列化时的规范顺序是水平组件后跟垂直组件。
当在语法中与其他关键字、<length> 或 <percentage> 一起指定时,<position> 是贪婪解析的;它会尽可能多地消耗组件。
8. 函数符号
函数符号是一种组件值类型,可以表示更复杂的类型或调用特殊处理。其语法以函数名称开始,紧跟左括号(即 <function-token>),然后是符号的参数,最后是右括号。与关键字一样,函数名称是不区分 ASCII 大小写的。空白在括号内紧邻处是被允许的,但非必须。函数可以接受多个参数,其格式类似于 CSS 属性值。
注意:一些遗留的函数符号(例如 rgba())不必要地使用了逗号,但通常逗号仅用于分隔列表中的项目,或在没有逗号就会产生歧义的语法片段中。如果使用逗号分隔参数,则逗号前后的空白是可选的。
background : url ( http://www.example.org/image ); color : rgb ( 100 , 200 , 50 ); content : counter ( list-item) ". " ; width : calc ( 50 % -2 em );
8.1. 数学表达式:calc()
calc() 函数允许将数字 CSS 组件值写为数学表达式,使用加法(+)、减法(-)、乘法(*)和/或除法(/)。
calc() 表达式表示其中包含的数学计算结果,该结果根据标准运算符优先级规则进行求值(* 和 / 的优先级高于 + 和 -,其余运算符按从左到右的顺序求值)。
它可用于任何允许 <length>、<frequency>、<angle>、<time>、<percentage>、<number> 或 <integer> 值的地方。calc() 表达式的组件可以是字面量值或 calc() 表达式。
:root{ font-size : calc ( 100 vw /40 ); }
如果设计的其余部分使用 rem 单位,则整个布局将缩放以匹配视口宽度。
.foo{ background : url ( top.png ), url ( bottom.png ); background-repeat : no-repeat; background-position : 50 % 50 % , calc ( 50 % +20 px ) calc ( 50 % +20 px ); }
.foo{ background-image : linear-gradient ( to right, silver, white50 px , whitecalc ( 100 % -50 px ), silver); }
8.1.1. 语法
calc() 函数的语法是
<calc () > =calc ( <calc-sum>) <calc-sum> = <calc-product>[ [ '+' |'-' ] <calc-product>] * <calc-product> = <calc-value>[ '*' <calc-value> |'/' <calc-number-value>] * <calc-value> = <number> | <dimension> | <percentage> |( <calc-sum>) <calc-number-sum> = <calc-number-product>[ [ '+' |'-' ] <calc-number-product>] * <calc-number-product> = <calc-number-value>[ '*' <calc-number-value> |'/' <calc-number-value>] * <calc-number-value> = <number> |( <calc-number-sum>)
此外,空白在 + 和 - 运算符的两侧都是必需的。(* 和 / 运算符周围可以使用而不带空白。)
用户代理必须支持至少 20 项的 calc() 表达式,其中每个 NUMBER、DIMENSION 或 PERCENTAGE 都是一项。如果 calc() 表达式包含的项数超过了支持的数量,它必须被视为无效。
8.1.2. 类型检查
数学表达式具有已解析类型(resolved type),它是 <length>、<frequency>、<angle>、<time>、<percentage>、<number> 或 <integer> 之一。已解析类型必须对于表达式放置的位置有效;否则表达式无效。表达式的已解析类型由其包含的值的类型决定。<number-token> 类型为 <number> 或 <integer>。<dimension-token> 的类型由其单位给定(cm 是 <length>,deg 是 <angle>,等等)。
注意:由于 <number-token> 始终被解释为 <number> 或 <integer>,因此 calc() 不支持“无单位 0”的 <length>。也就是说,width: calc(0 + 5px); 是无效的,即使 width: 0; 和 width: 5px; 都是有效的。
如果放置表达式的上下文中接受百分比,并且它们被定义为相对于 <number> 之外的另一种类型,则 <percentage-token> 将被视为该类型。例如,在 width 属性中,百分比具有 <length> 类型。百分比仅在以下情况下具有 <percentage> 类型:在当前上下文中,<percentage> 值与任何其他类型在“使用值”(used-value)上都不兼容。如果百分比在 calc() 中通常不被允许,则包含百分比的 calc() 表达式在该上下文中是无效的。
注意:请注意,相对于 <number> 的 <percentage>(例如在 opacity 中)在 calc() 中是不允许的。允许这种情况会导致“单位代数”(允许对 <dimension> 进行乘法/除法)出现严重问题,且到目前为止,在任何情况下都无法提供任何新的功能。(例如,opacity: 25% 等同于 opacity: .25;这只是一个微不足道的语法转换。)
注意:尽管有少数属性在“使用值”时纯 <number> 会变为 <length>(具体为 line-height 和 tab-size),但在 calc() 中 <number> 永远不会变得“像长度一样”。它们始终保持为 <number>。
运算符形成子表达式,这些子表达式根据其参数获得类型。为了简化表达式,运算符对其接受的类型有限制。在每个运算符处,都会根据这些限制检查左右参数的类型。如果兼容,类型将解析如下(为简单起见,以下忽略运算符的优先级规则)
- 在 + 或 - 处,检查两侧是否具有相同的类型,或者一侧是 <number> 而另一侧是 <integer>。如果两侧类型相同,则解析为该类型。如果一侧是 <number> 而另一侧是 <integer>,则解析为 <number>。
- 在 * 处,检查至少一侧是否为 <number>。如果两侧都是 <integer>,则解析为 <integer>。否则,解析为另一侧的类型。
- 在 / 处,检查右侧是否为 <number>。如果左侧是 <integer>,则解析为 <number>。否则,解析为左侧的类型。
如果运算符未通过上述检查,表达式无效。此外,除以零也是无效的。这既包括除以字面数字零,也包括任何计算结果为零的数字表达式(因为纯数字表达式可以在解析时无需任何额外信息进行计算)。
注意:代数简化不影响 calc() 表达式的有效性或其已解析类型。例如,calc(5px - 5px + 10s) 和 calc(0 * 5px + 10s) 都是无效的,因为它们试图将长度和时间相加。
8.1.3. 计算值
calc() 表达式的计算值是所有组件已计算的表达式。
如果百分比未在“计算值”时间解析,则它们不会在 calc() 表达式中解析,例如 calc(100% - 100% + 1em) 解析为 calc(1em + 0%),而不是 1em。如果值中有计算百分比的特殊规则(例如 height 属性),则只要 calc() 表达式包含百分比,它们就适用。
因此,background-position 的计算会保留 calc() 中的百分比,而 font-size 会将此类表达式直接计算为长度。
鉴于表格单元格和表格元素上宽度和高度计算的复杂性,涉及表格列、表格列组、表格行、表格行组和表格单元格中宽度和高度百分比的数学表达式,在自动布局和固定布局表格中,都可以视为已指定了 auto。
8.1.4. 范围检查
calc() 内部不执行解析时的值范围检查,因此超出范围的值不会导致声明变为无效。但是,表达式产生的值必须被限定(clamped)在目标上下文中允许的范围内。限定是在计算值上尽最大可能执行的,如果计算无法充分简化表达式以进行范围检查,也会在使用值上执行。(限定不会在指定值上执行。)
注意:这要求所有接受 calc() 的上下文将其允许的值定义为闭区间(而非开区间)。
width : calc ( 5 px -10 px ); width : calc ( -5 px ); width : 0 px ;
但请注意,width: -5px 不等同于 width: calc(-5px)!calc() 之外的超出范围的值在语法上是无效的,并会导致整个声明被丢弃。
8.1.5. 序列化
calc() 值的序列化在此级别中未定义。
附录 A:IANA 考量
about : invalid URL 方案的注册
本节根据 [RFC6694] 中定义的注册程序,定义并注册了 URL。
此注册的官方记录可在 http://www.iana.org/assignments/about-uri-tokens/about-uri-tokens.xhtml 找到。
| 注册令牌 | invalid
|
|---|---|
| 预期用途 | URL 引用了一个带有通用错误条件的非现有文档。它可以在需要 URL 但默认值不应被解析为任何类型的文档时使用。 |
| 联系人/变更控制者 | CSS WG <www-style@w3.org> (代表 W3C) |
| 规范 | CSS 值与单位模块 Level 3 |
致谢
Giovanni Campagna、Christoph Päper、Keith Rarick、Alex Mogilevsky、Ian Hickson、David Baron、Edward Welbourne、Boris Zbarsky、Björn Höhrmann 和 Michael Day 的评论和建议改进了此模块。
变更 (Changes)
自 2022 年 12 月 1 日候选推荐快照以来的变更包括
-
与 CSS Values and Units Module Level 4 的编辑同步。
-
为值定义语法添加了 <func()> 符号的定义。
-
明确了乘数堆叠。
-
明确了 <resolution> 不能为负。
自 2019 年 6 月 6 日候选推荐以来的变更包括
-
删除了 attr() 函数,因为它被推迟到 Level 5。
-
指定空 URL 的序列化为
。(问题 6447)url ( "" ) -
清理了本规范与 [CSS-CASCADE-3] 在定义 CSS 范围关键词时的交互。(问题 7439)
-
删除了 <length-number> 的定义,因为它无法与 calc() 结合使用。(问题 2789)
-
修复了 数字的定义,以允许十进制与科学记数法结合,如最初预期的那样,也如 [CSS-SYNTAX-3] 中所定义。(问题 7248)
-
编辑性改进。
自 2019 年 1 月 31 日候选推荐以来的变更包括
自 2018 年 8 月 14 日候选推荐以来的变更包括
- 定义了 <'property'> 语法以引用不带任何顶层 #-乘数的属性,以使该符号可用于通用的列表值属性模式。(问题 3146)
- 明确了如果更具体的规范定义了其他处理方式,则超出允许范围的数值不会被忽略。(问题 3270)
属性可能会将数值限制在一定范围内。如果该值超出允许范围,除非另有说明,则该声明无效且必须被忽略。
- 修复了一些 background-position 示例,使其不那么令人困惑。(问题 3482)
提供了一份评论处理意见。
自 2016 年 9 月 29 日候选推荐以来的变更包括
- 由于缺乏实现,删除了计算视口单位时考虑滚动条的内容。(问题 15)
- 内联了 <position> 定义并删除了三值语法,以允许在复杂语法中进行无歧义的结合。这实际上从 object-position 中删除了该语法,但允许 <position> 被重用,例如在 [CSS-TRANSFORMS-1] 中用于 3D 位置。(参见讨论。)
- 撤销了之前的更改,即允许零角度省略其单位;这将根据需要进行特殊处理以实现向后兼容性。(参见讨论)
- 定义了 calc() 值的范围检查以及由此产生的任何限定,在计算时间和使用时间同时执行。(问题 #434)
- 修复了语法错误,该错误禁止在 calc() 中使用数字表达式作为分母。(问题 12)
- 定义了在元素上下文之外处理字体相关单位的方法。(问题 9)
- 定义了当 0 模棱两可是 <number> 还是 <length> 时,将其解析为 <number>。(问题 489)
- 定义空 url() 指向无效 URL,而不是解析为样式表的 URL。(问题 2211)
- 删除了百分比在 calc() 中被视为 <number> 类型的(未使用的)能力。(问题 1463)
- 明确了高分辨率屏幕应锚定在设备像素上,而不是物理单位。(问题 8)
- 明确了 url() 的定义,规范性地说明它接受不带引号的语法。
- 定义了仅包含片段的 url() 会被特殊处理,始终作为页面内链接,而不管基 URL 如何干扰。(参见 § 3.4.1.1 片段 URL。)
- 根据 Syntax 规范而不是 CSS2.1 语法定义了 attr() 解析。
提供了一份评论处理意见。
自 2015 年 6 月 11 日候选推荐以来的变更包括
- 由于缺乏实现,删除了 toggle()。
- 允许零角度表示为 0。(因转换和渐变语法中的 Web 兼容性限制而更改。)
- 定义了片段 URL 的特殊处理。
- 定义了空 <url> 解析为无效资源。
- 定义了用于序列化的兼容单位和规范单位。
- 定义了 url() 属性参数的大小写敏感性,以匹配属性选择器。
- 将 <ident> 符号的定义添加到了标识符的定义中。
- 添加了 <length-percentage> 作为 <length> | <percentage> 的简写,以及角度、数字、时间和频率的等效生成式。
- 允许 calc() 内部的 <percentage> 作为它们自己的类型解析(如果它们出现在某些(目前是理论上的)上下文中,且与任何其他类型不兼容)。
- 各种澄清和编辑改进。
自 2013 年 7 月 30 日候选推荐以来的变更包括
- 规定在没有字体信息的情况下,1ch 等于 .5em。
- 添加了 Q 单位。
- 放宽了对 <custom-ident> 不必要的限制。要求引用它的规范对排除的关键字明确说明,因为新规则不像以前那么简单。
- 澄清了嵌入式样式表的相对 URL 解析。
- 澄清了 {A} 在 {A,B} 符号中的变体。
- 添加了用于限制使用 # 符号指定的逗号分隔列表长度的符号。
- 澄清了 toggle() 在简写声明中使用时的处理。
- 澄清了串联可重新排序的组合允许交叉。
- 将语法引用从 2.1 语法更改为 Syntax 规范。
提供了一份评论处理意见。
自 2012 年 8 月 28 日候选推荐以来的变更包括
- 将 attr() 语法中的
wqname更正为qname - 使得 attr() 中未定义的命名空间前缀会使函数无效。
- 根据 WG 决议,使 视口百分比单位考虑视口上的滚动条,除非 overflow 为 auto(在这种情况下,它们会忽略滚动条的存在)。
- 将 视口百分比单位在 分页媒体中的确切定义推迟到 CSS Paged Media。
- 添加回了 <custom-ident> 项作为便利符号,以便其他规范可以引用它。
自 2013 年 4 月 4 日候选推荐以来的变更包括
安全性考虑
本规范不提出新的安全考量。
本规范定义了 url() 函数(<url>),它允许 CSS 发出网络请求。根据它们所使用的功能,这些请求可能会暴露用户是否可以访问网络资源,并暴露有关其内容的信息(例如样式表内的规则、图像大小、字体度量)。它们还可能允许通过 URL 渗出数据。
隐私性考虑
本规范引入了暴露用户屏幕大小(视口百分比长度)、默认字体大小以及可能有关用户系统上可用字体的信息(字体相关长度)的单位。
本规范定义了 url() 函数(<url>),它允许 CSS 发出网络请求。根据它们所使用的功能,这些请求可能会暴露用户是否可以访问网络资源,并暴露有关其内容的信息(例如样式表内的规则、图像大小、字体度量)。它们还可能允许通过 URL 渗出数据。