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 Cascading and Inheritance
Level 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
|
全部 | A B C
| A && B && C
|
注意,所有“顺序任意”的情况都是用组合符表达的,而“顺序固定”都是并列变体。
2.5. 组件值与空白符
除非另有说明,空白符和/或注释可以出现在用上述组合符和乘子组合的组件之间、之前和之后。
注意: 在许多情况下,组件之间实际上必须有空格,以区分各自。例如,值 1em2em 会被解析为一个 <dimension-token>,数值为 1,标识符为 em2em,这是无效单位。此时,必须在 2 前添加空格,才能分别解析为 1em 和 2em 两个长度。
2.6. 函数式记法定义
函数式记法的语法定义为以下序列:
-
函数名写作标识符,后跟左括号(如 example(),或用 <function-token> 产生式表示任意函数名。
-
函数参数(如有),用值定义语法表达。
-
一个右括号字面量。
函数参数被视为隐式分组,相当于被方括号([ ... ])包围。
<pseudo-class-selector> =':' <ident-token> |':' <function-token> <any-value>')'
这表示任意函数名,<any-value> 为函数参数。
2.7. 属性值示例
以下是一些带有相应值定义字段的属性示例:
属性 | 值定义字段 | 示例值 |
---|---|---|
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 |
2.8. 非终结符定义与语法产生式块
像 <position> 或 <calc()> 这样的非终结符的精确定义,通常在CSS 语法产生式块中给出。这些定义通常以如下格式的预格式化区块表示:
每条定义单独占一行,由要定义的非终结符、一个 =
,以及其展开的值定义语法片段组成。定义可以跨多行,直到下一行以新产生式开头或到达产生式块结尾(以先到者为准)为止。
3. 值的组合:插值、加法与累积
某些过程(例如 过渡 和 动画)会组合两个 CSS 属性值。 下列组合操作——针对两个计算值 VA 和 VB,生成 计算值 Vresult——进行了定义。 对于非交换操作(如矩阵乘法或不匹配变换列表的累积),VA 表示操作的第一个项,VB 表示第二个项。
- 插值
-
给定两个属性值 VA 和 VB,
产生距离 p 的中间值 Vresult,其中 p = 0 时为
VA,p = 1 时为 VB。
p 的取值范围为 (−∞, ∞), 这是因为缓动函数的影响。 因此,该过程还必须定义 p 超出 [0, 1] 区间时的外推行为。
- 加法
-
给定两个属性值 VA 和 VB,
返回两者的和 Vresult。
注意:虽然加法通常可以用定义插值所用的加权和函数来表达, 但并非总是如此。 例如,变换矩阵的插值涉及分解并插值矩阵分量, 而加法依赖于矩阵乘法。
如果某个值类型未定义加法的具体过程,或被定义为不可加, 其 加法操作仅为 Vresult = VB。
- 累积
- 给定两个属性值 VA 和 VB, 返回将两个操作数组合的结果 Vresult, 其中 VB 被视为 VA 的增量。
这些操作仅定义在计算值上。 (因此,无需定义如 <length> 值 15pt 与 5em 如何相加,因为此类值会先被解析为规范单位后再传递给上述过程。)
3.1. 范围检查
插值可能导致结果值超出属性的有效范围,即使所有插值输入都是有效的; 这在 p 超出 [0, 1] 区间时尤其常见,但某些缓动函数即使在该区间内也可能导致超出。 如果在插值、加法、累积后最终结果超出目标上下文允许的范围, 并不会导致声明无效。 而是必须将该值裁剪(clamp)到目标上下文允许的范围, 裁剪方式与数学函数完全一致(参见§ 10.12 范围检查)。
注意: 即使插值结果超出范围,加法/累积可能“修正”结果使其回到有效范围。 因此,裁剪仅适用于应用所有插值相关操作后的最终结果。
4. 文本数据类型
文本数据类型 包括各种关键字和标识符,以及字符串(<string>)和 URL(<url>)。 除了预定义关键字的大小写或某些属性专门定义的情况外, 不会进行任何标准化处理,甚至不会进行 Unicode 标准化: 属性的指定值和计算值 就是解析后(包括字符集转换和转义)所提供的 Unicode 值。[UNICODE] [CSS-SYNTAX-3]
CSS 标识符, 通常用 <ident> 表示, 由符合 <ident-token> 语法的一系列字符组成。[CSS-SYNTAX-3] 标识符不能加引号; 否则会被当作字符串解析。 CSS 属性接受两类标识符:预定义关键字和作者自定义标识符。
注意: <ident> 产生式不用于属性值定义——应使用 <custom-ident>。它主要用于定义其他语法结构。
4.1. 预定义关键字
在值定义字段中,具有预定义意义的 关键字以字面量出现。 关键字属于标识符,并且ASCII 不区分大小写(即 [a-z] 和 [A-Z] 等价)。
4.1.1. CSS 全局关键字:initial、inherit 和 unset
如上所述,所有属性都接受CSS 全局关键字, 这些关键字表示所有 CSS 属性通用的值计算方式。 这些关键字在 CSS 层叠与继承模块中有规范性定义。
其他 CSS 规范也可以定义额外的全局关键字。
4.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> 应始终“位置明确”, 保证不会与任何属性关键字发生冲突。 也可以通过使用 <dashed-ident> 来避免此类冲突。
4.3. 有前缀的作者自定义标识符:<dashed-ident> 类型
某些场景既接受作者自定义标识符,也接受 CSS 定义的标识符。 如果不加以区分, 会导致 CSS 新增值时出现困难;UA 需要分析现有用法, 并冒险认为作者定义的标识符与新 CSS 值重复的概率足够低, 从而赋予新值特殊 CSS 意义不会破坏现有页面。
虽然 CSS 中有许多遗留情况正是这样混用两类值空间, <dashed-ident> 类型旨在为作者自定义标识符与 CSS 定义标识符的区分提供简便办法。
<dashed-ident> 产生式 是 <custom-ident>, 并具备完全区分大小写的特性, 还要求必须以两个连字符(U+002D HYPHEN-MINUS)开头。
<dashed-ident> 仅用于作者自定义名称。 CSS 永远不会为自身定义 <dashed-ident>。
.foo{ --fg-color : blue; }
@color-profile --foo{ src : url ( https://example.com/foo.icc ); } .foo{ color : color ( --foo1 0 .5 /.2 ); }
例如, 如果某 CSS 预处理器新增了一个“自定义” at 规则, 不应写作 @custom, 因为这会与将来官方的 @custom 规则冲突。 应该用 @--custom, 这样就保证不会与 CSS 已定义内容冲突。
更好的做法是用 @--library1-custom, 这样如果 Library2 也新增自己的 “custom” at 规则 (写作 @--library2-custom), 就不会发生冲突。 理想情况下,该前缀应是可配置的, 这样作者可以手动避免冲突。
4.4. 带引号的字符串:<string> 类型
字符串(String)由 <string> 表示。 当以字面值书写时, 它们由用双引号或单引号括起来的一系列字符组成, 对应于 <string-token> 产生式, 详见 CSS 语法模块 [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 中代表通用“换行”概念。)
4.5. 资源定位符:<url> 类型
<url> 类型, 通过 url() 和 src() 函数书写, 表示一个 URL, 即资源的指针。
<url> 的语法如下:
<url> = <url () > | <src () > <url () > =url ( <string> <url-modifier> * ) | <url-token> <src () > =src ( <string> <url-modifier>*)
出于兼容性原因,url() 可以在不加引号的情况下书写 URL,此时会被特殊解析为 <url-token> [CSS-SYNTAX-3]。 因为这种特殊解析,url() 只能直接指定 URL;src() 不具备该解析规则, 因此其 URL 可以通过函数提供, 如 var()。
background : url ( "http://www.example.com/pinkish.gif" ); background : url ( http://www.example.com/pinkish.gif );
下面这两种写法也有同样效果:
background : src ( "http://www.example.com/pinkish.gif" ); --foo : "http://www.example.com/pinkish.gif" ; background : src ( var ( --foo));
但这样写是不可以的:
--foo : "http://www.example.com/pinkish.gif" ; background : url ( var(--foo ));
……因为值中的未转义 "(" 会导致解析错误,使整个声明被视为无效丢弃。
未加引号 url() 语法的精确定义见 [CSS-SYNTAX-3]。
某些 CSS 场景(如 @import)也允许用裸 <string> 表示 <url>,无需函数包装。 在这种情况下,该字符串的行为与包裹同内容的 url() 一致。
4.5.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" ) }
位于样式表:
http : //www.example.org/style/basic.css
则源文档的 <body>
背景会平铺该 URL 所指向的资源:
http : //www.example.org/style/tile.png
无论包含 <body>
的源文档 URL 如何,使用的都是同一图片。
4.5.1.1. 片段 URL
为使元素 ID 引用在 CSS 中无论基准 URL 如何变化或有无 shadow DOM 都能工作,当 <url> 仅包含片段时具备特殊行为。
如果 <url> 的值以
U+0023 井号(#
)字符开头,
则该 URL 还会设置 本地 url 标志,
并且是该 URL 树作用域引用,针对该 URL 的 片段。
-
如果该 URL 的片段是元素 ID 引用(而非媒体片段等), 则按 树作用域引用、以树的 ID 为树作用域名称的方式解析: 具体来说,从相关节点树的后代中按树顺序找到片段作为ID的第一个元素。 (如 树作用域引用 通常行为,如果需要可向上查找宿主树。)
如未找到该元素,则该 URL 无法解析。
-
否则,将片段相对于当前文档解析。
可能需要引用 查找潜在指示元素,
但该定义仅适用于 Document
,
不适用于 ShadowRoot
。
注意: 这意味着此类片段将始终相对于当前文档内容(或样式表所在的节点树,如有 shadow
DOM)解析,
而不考虑其他地方的相对 URL 解析方式(如 base
元素改变基准 URL,或外链样式表的相对 URL 按样式表 URL 解析等)。
#anchor
会相对于 http : //example.com/
解析,而 #image
则会在 HTML 文档自身元素中解析:
<!DOCTYPE html> < base href = "http://example.com/" > ...< a href = "#anchor" style = "background-image: url(#image)" > link</ a >
当序列化一个带有 本地 url 标志 的 url() 时, 只需序列化出片段部分。
4.5.2. 空 URL
如果 <url> 的值为空字符串 (如 url("") 或 url()), 则该 url 必须解析为无效资源(类似 about:invalid)。
其计算值为 url("") 或 src(""), 以实际指定为准, 序列化时也应如此。
注意: 这与 Web 平台其他地方嵌入资源的空 url 行为一致, 避免因编辑错误导致 url() 为空而反复请求样式表或主文档, 因为对于 url() 出现的地方,这几乎必然是无效资源。 Web 平台的链接允许空 url, 因此如果 CSS 以后支持超链接控制, 可以在相应场景放宽此限制。
4.5.3. URL 修饰符
<url> 支持指定额外的 <url-modifier>, 用于以某种方式改变 URL 的意义或解释。 <url-modifier> 可以是 <ident> 或 函数式记法。
本规范未定义任何 <url-modifier>, 但其他规范可以定义。
注意: 未加引号或未用 url() 包裹的 <url> 不能接受任何 <url-modifier>。
4.5.4. URL 处理模型
CSSStyleSheet
sheet,
一个匹配 RequestDestination
的字符串 destination,
一个 "no-cors" 或 "cors" 的 corsMode,
以及一个接受 response 及 null、failure 或字节流的算法 processResponse:
-
令 environmentSettings 为 sheet 的 相关设置对象。
-
令 base 为 sheet 的 样式表基准 URL(如不为 null), 否则为 environmentSettings 的 API 基准 URL。[CSSOM]
-
令 parsedUrl 为 URL 解析器步骤的结果, 以 urlValue 的 url 和 base 为参数。 若算法返回错误,则返回。
-
令 req 为新建的 请求,其 url 为 parsedUrl, destination 为 destination,mode 为 corsMode,origin 为 environmentSettings 的 origin,credentials mode 为 "same-origin",use-url-credentials flag 设为 true, client 为 environmentSettings, referrer 为 environmentSettings 的 API 基准 URL。
-
应用所有适用于该请求的 URL 请求修改步骤。
注意: 本规范未定义任何 URL 请求修改步骤, 但其它规范可定义。
-
如果 req 的 mode 为 "cors", 则将 req 的 referrer 设为 sheet 的 location。[CSSOM]
-
如果 sheet 的 origin-clean flag 被设置, 则将 req 的 initiator type 设为 "css"。[CSSOM]
-
Fetch req, 并将 processresponseconsumebody 设为 processResponse。
在解析 CSS 中的 URL 时, URL 解析器 的 encoding 参数 必须省略 (即使用默认 UTF-8), 无论样式表的编码为何。
注意: 换句话说,CSS 中书写的 URL 总是会在 百分号编码非 ASCII 码点时,使用 UTF-8 编码到 URL 对象中(因此当将 URL 值用于如网络请求等场景时总是如此),与样式表本身的编码无关。注意,此过程发生在将样式表解码为 Unicode 码点之后。
5. 数值数据类型
数值数据类型用于表示数量、索引、位置等值。 虽然表达数值(数值部分)本身有多种语法变体, 但指定值和计算值不会区分这些变体: 它们代表值的抽象数量,而不是其语法表现形式。
数值数据类型 包括 <integer>、<number>、<percentage>, 以及各种带单位数值,如 <length>、<angle>、<time>、<frequency>、<resolution> 等。
注意:虽然通用带单位数值在此定义, 但其他一些模块还定义了更多数据类型 (如 [css-grid-1] 引入了 fr 单位), 它们的用途更为局部化。
CSS 中数值的精度和支持的范围是由实现定义的, 并且可能会根据值所用的属性或上下文而异。 但在 CSS 规范中, 假定为无限精度和范围。 如果由于实现的范围/精度限制而无法明确支持某个值, 则必须将其转换为实现所支持的最接近的值, 但实现如何定义“最接近”也是由实现定义的。
如果由于超出实现定义的支持范围而必须转换<angle>, 则必须将其裁剪为最接近的 360deg 的倍数。
5.1. 范围限制与范围定义记法
属性可以将数值限制在某个范围内。
如果值超出允许范围,
除非另有说明,
该声明无效,必须被忽略。
可以使用CSS 方括号范围记法(
)在数值类型的尖括号内、关键字后标注范围,
表示封闭区间(包含 min 和 max)。
例如,<integer [0,10]> 表示整数在 0 到 10 之间(含端点),
<angle
[0,180deg]> 则表示角度在 0deg 到 180deg 之间(可为任意单位)。
注意: CSS 值通常不允许开区间,因此只用方括号表示法。
理论上 CSS 支持所有值类型的无限精度和无限范围; 但实际上实现有有限能力。UA 应支持合理有用的范围和精度。 理想情况下无限的范围可用 ∞ 或 −∞ 表示。 例如,<length [0,∞]> 表示非负长度。
如果未标注范围,
无论是通过方括号范围记法还是属性描述,
则假定为
。
−∞ 或 ∞ 的值必须无单位书写, 即使该类型通常带单位。 0 可以无单位书写, 即使该类型通常不允许“无单位零” (如 <time>)。
注意: 撰写本规范时,
方括号范围记法尚属新内容;
因此多数 CSS 规范中的范围限制只用文字描述。
(如“负值无效”或“负值不允许”表示
范围。)
这些说明同样具有限制效力。
5.2. 整数:<integer> 类型
整数值用 <integer> 表示。
当以字面值书写时, 整数 是一个或多个十进制数字 0 到 9,对应于 CSS 语法模块<number-token> 产生式的一个子集。[CSS-SYNTAX-3] 整数的首位数字可前置 - 或 + 表示正负号。
除非另有说明, 在 CSS 规范中,四舍五入到最接近整数要求在小数部分恰为 0.5 时向 +∞ 方向取整。 (如 1.5 向上取整为 2,-1.5 则为 -1。)
5.2.1. <integer> 的计算与组合
除非另有说明, 指定的 <integer> 的计算值为指定的抽象整数。
插值的 <integer> 定义为:Vresult = round((1 - p) × VA + p × VB); 即先在实数空间插值(和 <number> 一样),结果再用四舍五入到最接近整数转换为 <integer>。
加法的 <integer> 定义为 Vresult = VA + VB
5.3. 实数:<number> 类型
数值用 <number> 表示, 代表实数,可以带小数部分。
当以字面值书写时, 数值可以是整数, 或零个或多个十进制数字后跟小数点(.)再跟一个或多个十进制数字; 还可在末尾加字母“e”或“E”再跟一个整数,表示科学计数法下的十进制指数。 它对应于 <number-token> 产生式, 见 CSS 语法模块 [CSS-SYNTAX-3]。 与整数一样,数值首位可加 - 或 + 表示正负号。
<zero> 代表值为 0 的数值字面量。 只要表达式结果为 <number> 且值为 0 (如 calc(0)), 并不匹配 <zero>; 只有字面 <number-token> 匹配。
5.3.1. <number> 的计算与组合
除非另有说明, 指定的 <number> 的计算值为指定的抽象数值。
插值的 <number> 定义为 Vresult = (1 - p) × VA + p × VB
加法的 <number> 定义为 Vresult = VA + VB
5.4. 带单位数值:dimension 值
通用术语 带单位数值 指带有单位标识符的数值; 用 <dimension> 表示。
当以字面值书写时, 带单位数值 是一个 数值 紧接单位标识符, 单位是一个标识符。 对应 <dimension-token> 产生式, 见 CSS 语法模块 [CSS-SYNTAX-3]。 单位标识符同关键字一样,ASCII 不区分大小写。
CSS 用 <dimension> 表示 距离(<length>), 时长(<time>), 频率(<frequency>), 分辨率(<resolution>)等量值。
5.4.1. 兼容单位
序列化计算值时 [CSSOM], 兼容单位(指可用静态比例因子换算的单位,如 px 和 in 之间的 96:1 比例, 或 font-size 计算值下 em 和 px 之间的比例) 会被转换为唯一的规范单位。 每组兼容单位会指定其中哪个作为规范单位用于序列化。
序列化已解析值(即已用值)时, 所有代表长度的值类型(百分比、数值、关键字等)都视为与长度兼容。 同理,未来返回 已用值 的 API 必须将所有代表距离/时长/频率等的值视为与相关类别 带单位数值兼容,并据此规范化。
5.4.2. 带单位数值的组合
插值兼容的单位的带单位数值(比如两个 <length> 值) 定义为 Vresult = (1 - p) × VA + p × VB
加法兼容单位的带单位数值,定义为 Vresult = VA + VB
5.5. 百分比:<percentage> 类型
百分比值用 <percentage> 表示, 表示某个参考值的一定比例。
当以字面值书写时, 百分比为一个 数值 紧跟百分号 %。 对应 <percentage-token> 产生式, 见 CSS 语法模块 [CSS-SYNTAX-3]。
百分比值总是相对于另一个量(如长度)。 每个允许百分比的属性还会定义百分比所参考的量。 该量可为同一元素其他属性的值、祖先元素属性的值、排版上下文的某个测量 (如 包含块的宽度), 或其他内容。
5.5.1. <percentage> 的计算与组合
除非另有说明 (如 font-size 会将其 <percentage> 值计算为 <length>), 百分比的计算值 就是指定的百分比。
插值的 <percentage> 定义为 Vresult = (1 - p) × VA + p × VB
加法的 <percentage> 定义为 Vresult = VA + VB
5.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.6.1. 百分比与带单位数值混合的计算与组合
百分比-带单位混合值的计算值定义如下:
-
若百分比部分为 0 或明确指定为计算为带单位值,则为带单位值
-
若带单位部分为 0,则为百分比
百分比-带单位值组合(如 <length-percentage>、<frequency-percentage>、<angle-percentage>、<time-percentage> 或等价记法)的插值定义为:
- 当 VA 与 VB 都为纯 <length> 时,等价于 长度插值
- 当 VA 与 VB 都为纯 <percentage> 时,等价于 百分比插值
- 否则等价于将二者都转为 calc() 表达式,表示带单位类型和百分比的和(各自可为0),分别对每个分量进行插值 (带单位如 <length> / <frequency> / <angle> / <time>,百分比为 <percentage>)
加法的 <percentage> 的定义与插值一致,只是每个分量是相加而非插值。
5.7. 比例:<ratio> 类型
比例值用 <ratio> 表示, 代表两个数值的比值。 它通常用来表示宽高比(第一个为宽度,第二个为高度)。
当以字面值书写时, 比例 语法如下:
<ratio> = <number[ 0 , ∞] >[ / <number[ 0 , ∞] >] ?
第二个 <number> 可省略,默认值为 1。 但 <ratio> 序列化时总会写出两个分量。
<ratio> 的计算值为指定的数字对。
如果 <ratio> 中任一数为 0 或无穷, 则代表退化比例(通常不会有效果)。
如果要比较两个 <ratio>, 将第一个数除以第二个数后比较。 例如 3/2 小于 2/1, 因为前者为 1.5,后者为 2。 (换言之,“高”宽高比小于“宽”宽高比。)
5.7.1. <ratio> 的组合
<ratio> 的插值定义为: 先将每个 <ratio> 转为数字(第一个值除以第二个值,如 3 / 2 得 1.5), 再取对数(如 1.5 得约 0.176), 然后对这些值做插值。 插值中间结果再取指数反函数, 最后按“结果为第一个值,第二个为 1”解释为 <ratio>。
start =log ( 5 ); // ≈0.69897 end =log ( 1.5 ); // ≈0.17609 interp =0.69897 *.5 +0.17609 *.5 ; // ≈0.43753 final =10 ^interp; // ≈2.73
注意: 用比值的对数插值,保证结果与比例大小无关 (如 5 / 1 到 300 / 200 得到的结果与上例相同), “宽”与“高”对称 (如 1 / 5 到 2 / 3 的中点约为 1 / 2.73), 并且无论宽为基准还是高为基准都对称。 这些是许多其它插值策略不具备的特性。
注意: 由于对数的性质, 可用任意对数,例子用的是 base-10, 但如用自然对数 e,插值中间结果不同,最终结果一致。
两个 <ratio> 不支持加法。
6. 距离单位:<length> 类型
长度指距离的度量,在属性定义中用 <length> 表示。 长度是一种带单位数值。
对于零长度,单位标识符是可选的 (即可以语法上写作 <number> 0)。 但如果 0 在某属性中既可解析为 <number>,也可解析为 <length> (比如 line-height), 则必须解析为 <number>。
属性可以对长度值进行范围限制。 如果值超出允许范围, 声明无效,必须被忽略。
虽然某些属性允许负长度值, 这可能会使排版变得复杂,并且可能有实现相关的限制。 如果允许但无法支持负长度值, 必须将其转换为能支持的最接近值。
在无法支持已用长度的情况下, 用户代理必须在实际值中做近似。
长度单位分为两类:相对和绝对。 长度的指定值(指定长度)由其数值和单位组成。 长度的计算值(计算长度)为指定长度解析为绝对长度, 单位不区分: 可以用任意绝对长度单位表示(但序列化时会用它的规范单位,即 px)。
虽然数值的精度支持情况及其如何舍入通常是由实现定义的,但 <length> 在 border-width 及少数其他属性中 会以特定方式舍入, 以确保良好的视觉显示。 (此算法由各属性显式调用。)
6.1. 相对长度
相对长度单位表示相对于另一个长度的长度。 使用相对单位的样式表更易于在不同输出环境间缩放。
相对单位有:
单位 | 相对于 |
---|---|
em | 元素的字体大小 |
ex | 元素字体的 x 高度 |
cap | 元素字体的大写字母高度 |
ch | 元素字体中窄字形(如“0”)的典型字形进位宽度 |
ic | 元素字体中全角字形(如“水”)的典型字形进位宽度 |
rem | 根元素的字体大小 |
lh | 元素的行高 |
rlh | 根元素的行高 |
vw | 视口宽度的 1% |
vh | 视口高度的 1% |
vi | 根元素行内轴方向视口大小的 1% |
vb | 根元素块轴方向视口大小的 1% |
vmin | 视口较小维度的 1% |
vmax | 视口较大维度的 1% |
子元素不会继承其父元素指定的相对值; 它们继承计算值。
6.1.1. 字体相对长度:em、rem、ex、 rex、cap、rcap、ch、rch、 ic、ric、lh、rlh 单位
字体相对长度指基于字体度量的长度, 可为使用该单位的元素自身字体度量 (局部字体相对长度), 也可为根元素的字体度量 (根字体相对长度)。
- em
- 等于使用该单位元素的 font-size 属性的计算值。
- rem
- 等于根元素上 em 单位的计算值。
- ex
- 等于首选字体的实际 x 高度 [CSS3-FONTS]。 x 高度通常等于小写 x 的高度。 但即使字体不含 "x" 也有 ex 的定义。 x 高度可有多种方式获得。 有些字体提供可靠的 x 高度度量。 若无可靠度量,UA 可用小写字形高度近似。 一种启发是取小写 "o" 超出基线的距离,再用其外框顶减去该值。 如无法或不便确定 x 高度,必须假定为 0.5em。
- rex
- 等于根元素上 ex 单位的值。
- cap
- 等于首选字体的实际大写高度 [CSS3-FONTS]。 大写高度约等于大写拉丁字母的高度。 但即使不含拉丁字母也有 cap 单位。 cap 高度可多种方式获得。 有些字体有可靠 cap 高度度量。 若无可靠度量,UA 可用大写字形高度近似。 一种启发是取大写 “O” 超出基线的距离,再用其外框顶减去该值。 如无法或不便确定 cap 高度,应使用字体的 ascent。
- rcap
- 等于根元素上 cap 单位的值。
- ch
-
表示欧洲字母数字的典型进位宽度,为该字体中 “0” (U+0030) 的实际进位宽度。
(进位宽度指字形在元素行内轴方向的 advance width 或 height。)
注意: 此度量为近似值(等宽字体下为精确值), 方便基于字形数估算宽度。
注意: 字形进位宽度受书写模式、文本方向、字体设置、text-transform 及其他影响字形选择或方向的属性影响。
如无法或不便确定 “0” 的度量, 应假定宽为 0.5em,高为 1em。 因此 ch 单位一般为 0.5em, 竖排时为 1em (如 writing-mode 为 vertical-rl 或 vertical-lr 且 text-orientation 为 upright)。
- rch
- 等于根元素上 ch 单位的值。
- ic
-
表示 CJK 字母的典型进位宽度,为所用字体中 “水” (U+6C34) 的实际 进位宽度。
注意: 这个度量通常是精确值(极少数全角字形比例字体中为近似值), 便于基于字形数估算宽度。
如无法或不便确定汉字进位宽度,应假定为 1em。
- ric
- 等于根元素上 ic 单位的值。
- lh
- 等于元素 line-height 属性的计算值, 其中 normal 通过仅用首选字体的度量转为绝对长度。
- rlh
-
等于根元素上 lh 单位的值。
注意: 用 height 属性指定 lh 或 rlh 单位, 并不能让作者控制实际行数, 这些单位只用于理论上理想空行的长度计算; 实际行盒大小因内容而异。 如需限制元素实际行数,可用 max-lines 属性。
在元素上用于 font-* 属性值时, 字体相对长度 以父元素的计算度量为基准——如无父元素,则以 font 和 line-height 属性的初始值度量。 同理, lh 或 rlh 单位用于 line-height 或 font-* 属性值时, 以父元素的 line-height 和字体度量为基准——如无父元素,则以 font 和 line-height 的初始值度量。 (其他字体相对长度在 line-height 属性中依然基于元素自身度量。)
在非元素上下文中使用(如 媒体查询), 字体相对长度 单位以 font 和 line-height 属性的初始值度量为基准。 同理,文档无根元素时, 根字体相对长度以 font 和 line-height 的初始值度量解析。
注意: ch、ic 等字体相对单位可能会触发字体下载, 如所需字体尚未加载。
字体相对长度的计算不考虑字形变形。
有些用户代理允许用户为文档字体大小加以限制,如设置最小字体以保证可读性。 这些限制只应用于受影响属性的已用值; 不得影响属性中 字体相对长度的解析。 但在其他场景(如 媒体查询), 若限制影响字体度量, 则会影响 字体相对长度的解析。
注意: 一般来说,尊重用户偏好(如最小字体)是有益的; 例如 (min-width: 40em) 媒体查询用实际字体大小对齐有用。 但让这些偏好影响元素属性中的字体相对长度,不符合 Web 兼容性; 太多页面要求这些单位是指定 font-size 的精确倍数, 而不是应用用户偏好后的实际字体大小。
有些用户代理对表单控件的 line-height 值有限制。 这些限制对 lh 和 rlh 单位没有影响。 但对子元素的影响为由实现定义。
6.1.2. 视口百分比长度:*vw、*vh、*vi、*vb、*vmin、*vmax 单位
视口百分比长度相对于初始包含块的大小—— 即基于视口大小(连续媒体)或页面区域(分页媒体)的大小。 改变初始包含块的宽高时,它们会相应缩放。
6.1.2.1. 大、小与动态视口尺寸
视口百分比单位有四种变体, 分别对应三种(可能相同)视口尺寸概念。
- large viewport
-
大视口百分比单位(lv*)
和 默认视口百分比单位(v*)
以 大视口尺寸为基准:
该视口尺寸假定所有UA可动态展开/收起的界面都已收起。
这样作者可确保内容填满整个视口,
但这些内容在界面展开时可能会被遮挡。
大视口百分比单位的尺寸是固定的(因此稳定),除非视口本身调整。
例如,在手机上, 屏幕空间有限, 浏览器常在用户滚动页面后隐藏标题栏和地址栏。 大视口百分比单位相对于这些界面收起后的空间, 所以用这些单位的内容在界面收起时会填满整个可见页面。 但界面显示时,这些单位定位或大小的内容可能会被遮挡。 - small viewport
-
小视口百分比单位(sv*)
以 小视口尺寸为基准:
该视口尺寸假定所有UA可动态展开/收起的界面都已展开。
这样作者可确保内容即使界面展开也不会被遮挡,
但界面收起时内容可能不会填满视口。
小视口百分比单位的尺寸是固定的(因此稳定),除非视口本身调整。
例如,height: 100svh 的元素, 在所有 UA 动态界面显示时会完美填满屏幕,不会内容被遮挡。但这些界面收起后,该元素周围会有额外空间。 小视口百分比单位通常更安全, 但用户与页面交互后可能布局不最优。
- dynamic viewport
-
动态视口百分比单位(dv*)
以 动态视口尺寸为基准:
即考虑动态展开/收起的所有UA界面后的视口大小。
这样作者可确保内容无论界面在否都能完全适配视口。
动态视口百分比单位的尺寸即使视口本身不变也不稳定。 使用这些单位可能导致内容在滚动等操作中随时重排, 可能影响用户体验和性能。
UA 不要求在界面动画(展开/收起)时对 动态视口百分比单位 进行动画, 可以直接按界面完全展开或收起时计算单位。 (建议 UA 在此期间假定完全收起尺寸。)
某一界面的展开/收起 (A) 是否导致所有 视口百分比长度(及初始包含块)同时改变, 还是 (B) 只体现在 大视口尺寸 与 小视口尺寸 的差异, 主要由 UA 决定。 但:
-
因滚动或频繁交互导致界面变化,若变化会引发较大布局变化,必须归类为后者(B)。
-
界面变化如有稳定状态,重新布局有益用户,则归类为前者(A)。
-
UA 也可有些动态显示界面特意叠加在内容上,不触发布局变化,因此不影响任何视口百分比长度。 (通常屏幕键盘属于此类。)
无论何种情况, 若 overflow 或 scrollbar-gutter 在 根元素任一轴上 会无条件导致滚动条出现(或预留空间) (如 overflow: scroll,但不是 overflow: auto), 该轴的 视口百分比长度计算值 会按初始包含块减少。 否则, 且在 媒体查询下始终如此, 视口百分比长度假定无滚动条 (即使与初始包含块不一致)。
注意: overflow 在 body 元素 上有时会影响 根元素 是否出现滚动条。 但这不会影响视口单位大小。
6.1.2.2. 各种视口相关单位
视口百分比长度单位包括:
- vw
- svw
- lvw
- dvw
- svw
- 分别等于 大视口尺寸、小视口尺寸、大视口尺寸 和 动态视口尺寸 宽度的 1%。
- vh
- svh
- lvh
- dvh
- svh
- 分别等于 大视口尺寸、小视口尺寸、大视口尺寸 和 动态视口尺寸 高度的 1%。
- vi
- svi
- lvi
- dvi
- svi
- 分别等于盒子的 大视口尺寸、小视口尺寸、大视口尺寸 和 动态视口尺寸 在 行内轴 上的大小的 1%。
- vb
- svb
- lvb
- dvb
- svb
- 分别等于盒子的 大视口尺寸、小视口尺寸、大视口尺寸 和 动态视口尺寸 在 块轴 上的大小的 1%。
- vmin
- svmin
- lvmin
- dvmin
- svmin
- 等于 *vw 与 *vh 中较小者。
- vmax
- svmax
- lvmax
- dvmax
- svmax
- 等于 *vw 与 *vh 中较大者。
注意: 最初(无前缀)视口单位定义为相对于初始包含块, 在连续媒体中总是与唯一视口尺寸一致。 浏览器 chrome 在滚动中动态变化是后来的发明,大多数 UA 按 Safari 的实现将这些单位映射到较大尺寸。 这种定义在很多场合更美观,但也可能遮挡关键内容(如工具栏、头部、底部)。 因此这种映射是否最佳尚无定论,早期规范允许 UA 选择默认单位的映射。 但目前为 Web 兼容性,假定必须映射到大视口百分比单位。
无元素或尚未样式化时(如评估媒体查询), *vi 和 *vb 单位用 writing-mode 属性的初始值决定各自的轴。
6.2. 绝对长度:cm、mm、Q、in、pt、pc、px 单位
绝对长度单位彼此有固定关系,并锚定到物理度量。 主要用于已知输出环境时。 绝对单位包括 物理单位(in、cm、mm、pt、pc、Q) 和 视觉角度单位(像素单位)(px):
单位 | 名称 | 换算关系 |
---|---|---|
cm | 厘米 | 1cm = 96px/2.54 |
mm | 毫米 | 1mm = 1cm 的 1/10 |
Q | 四分之一毫米 | 1Q = 1cm 的 1/40 |
in | 英寸 | 1in = 2.54cm = 96px |
pc | 派卡(pica) | 1pc = 1in 的 1/6 |
pt | 点(point) | 1pt = 1in 的 1/72 |
px | 像素 | 1px = 1in 的 1/96 |
h1{ margin : 0.5 in } /* 英寸 */ h2{ line-height : 3 cm } /* 厘米 */ h3{ word-spacing : 4 mm } /* 毫米 */ h3{ letter-spacing : 1 Q } /* 四分之一毫米 */ h4{ font-size : 12 pt } /* 点 */ h4{ font-size : 1 pc } /* 派卡 */ p{ font-size : 12 px } /* px */
注意: 出版领域的长度有时写作
,
表示 2 派卡 3 点的长度。
在 CSS 中可写作 calc(2pc + 3pt)(参见 § 10.1 基本算术:calc())。
对于 CSS 设备,这些尺寸的 锚定单位可通过以下任一方式:
对于典型阅读距离下的印刷介质, 锚定单位应为物理单位(英寸、厘米等)。 对于屏幕介质(包括高分辨率设备)、低分辨率设备及其它特殊距离设备, 推荐用 锚定单位 为像素单位。 这类设备建议 像素单位 指向最接近参考像素的整数个设备像素。
注意: 当锚定单位是像素单位时, 物理单位可能与实际物理尺寸不符。 若 锚定单位为物理单位, 像素单位可能无法与整数个设备像素精确对应。
注意: 本规范对像素单位与物理单位的定义不同于 CSS1、CSS2 早期版本。 早期版本中,像素单位和物理单位没有固定比例: 物理单位始终与物理尺寸相关,而像素单位会随参考像素变化。 (此变更主要是因大量现有内容假定 96dpi,改变会严重破坏兼容性。)
注意: 单位ASCII 不区分大小写,序列化为小写,例如 1Q 序列化为 1q。
参考像素 指在 96dpi 设备上、与读者一臂距离处的一个像素所对应的可视角度。 臂长约 28 英寸时,可视角约 0.0213 度。 按臂长距离阅读时,1px 约为 0.26 mm(1/96 英寸)。
下图展示了视距对参考像素大小的影响: 71 cm(28 英寸)时,参考像素为 0.26 mm, 3.5 m(12 英尺)时,参考像素为 1.3 mm。

下图展示了设备分辨率对像素单位的影响:1px*1px 区域在低分辨率设备(如普通显示器)由一个点覆盖,在高分辨率设备(如打印机)由 16 个点覆盖。

设备像素 是设备输出上能显示全色域的最小面积单元。 常见彩色屏幕中为包含红绿蓝子像素的正方形或矩形区域。 许多非传统输出可能模糊此定义,如某些颜色分辨率更高的设备。 这些设备仍会暴露等价的“设备像素”概念。
7. 其他数量单位
7.1. 角度单位:<angle> 类型及 deg、grad、rad、turn 单位
角度值是<dimension>,用 <angle> 表示。 角度单位标识符包括:
- deg
- 度。一个完整圆有 360 度。
- grad
- 梯度,也称为“gon”或“grade”。一个完整圆有 400 梯度。
- rad
- 弧度。一个完整圆有 2π 弧度。
- turn
- 圈。一个完整圆为 1 turn。
例如,直角可写作 90deg、100grad、0.25turn 或约 1.57rad。
所有 <angle> 单位都是兼容的, deg 是它们的规范单位。
例如,在 linear-gradient() 函数中, 用于确定渐变方向的 <angle> 就按方位角解释。
注意: 出于兼容性原因, 某些 <angle> 的用法允许裸 0 表示 0deg。 但这不是通用规则,未来也不会出现在 <angle> 类型的新用法中。
7.2. 时长单位:<time> 类型及 s、ms 单位
时间值是带单位数值,用 <time> 表示。 时间单位标识符包括:
- s
- 秒。
- ms
- 毫秒。1 秒等于 1000 毫秒。
所有 <time> 单位都是兼容的, s 是它们的规范单位。
属性可以限制时长值的取值范围。 如果值超出允许范围, 声明无效,必须被忽略。
7.3. 频率单位:<frequency> 类型及 Hz、kHz 单位
频率值是带单位数值,用 <frequency> 表示。 频率单位标识符包括:
- Hz
- 赫兹。表示每秒发生的次数。
- kHz
- 千赫兹。1 千赫兹等于 1000 赫兹。
例如,表示声音音高时,200Hz(或 200hz)是低音,6kHz(或 6khz)是高音。
所有 <frequency> 单位都是兼容的, hz 是它们的规范单位。
注意: 单位ASCII 不区分大小写,序列化为小写,如 1Hz 序列化为 1hz。
7.4. 分辨率单位:<resolution> 类型及 dpi、dpcm、dppx 单位
分辨率单位是带单位数值,用 <resolution> 表示。 分辨率单位标识符包括:
- dpi
- 每英寸点数。
- dpcm
- 每厘米点数。
- dppx
- x
- 每 px 单位的点数。
<resolution> 单位表示图形表现中单个“点”的大小,即每个 CSS in、cm 或 px 中包含多少个点。 用法见如 resolution 媒体查询([MEDIAQ])或 image-resolution 属性([CSS3-IMAGES])。
所有 <resolution> 单位都是兼容的, dppx 是它们的规范单位。
<resolution> 的取值范围始终排除负值,此外还可有其他显式范围限制。
注意,由于 CSS in 与 CSS px 的 1:96 固定比例,1dppx 等价于 96dpi。 这与 CSS 下图片的默认分辨率对应,详见 image-resolution。
@media ( min-resolution:2 dppx ) { ...}
8. 其他地方定义的数据类型
某些数据类型在其各自的模块中定义。 本例介绍了多个规范中常用的一些类型。
8.1. 颜色:<color> 类型
<color> 数据类型在 [CSS-COLOR-4] 中定义。 UA 必须按照该规范解释 <color>。
8.1.1. <color> 的组合
插值的 <color> 在 CSS Color 4 § 12. 色彩插值 中定义。 插值在预乘色彩间进行,详见 CSS Color 4 § 12.3 含 Alpha 的插值。
注意: CSS 工作组欢迎反馈对 <color> 求和的用例,将来有可能使 <color> 支持可加性。
8.2. 图像:<image> 类型
<image> 数据类型见 [CSS3-IMAGES]。 支持 CSS Images Level 3 或更高的 UA 必须按规范解释 <image>。 不支持 CSS Images Level 3 的 UA 必须将 <image> 按 <url> 处理。
8.2.1. <image> 的组合
注意: <image> 的插值在 CSS Images 3 § 6 插值 中定义。
图像不可加。
8.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 属性还接受三值语法。 但这已被通用上禁用,因为与其他长度或百分比成分组合时会造成解析歧义。
8.3.1. <position> 的解析
当与其他关键字、<length> 或 <percentage> 并列出现于语法中时,<position> 会贪婪地解析,尽可能多地消耗成分。
8.3.2. <position> 的序列化
序列化 指定值的 <position> 时:
- 只指定一个成分时:
-
-
自动补上 center 关键字,序列化为二值形式。
-
- 指定两个成分时:
-
-
关键字按关键字序列化。
-
<length-percentage> 按原样序列化。
-
成分序列化顺序为先水平后垂直。
-
- 指定四个成分时:
-
-
关键字和偏移量都序列化。
-
成分序列化顺序为先水平后垂直。
-
注意: <position> 值序列化时不写作单值, 即使单值行为一致, 这样避免在某些语法中(如 <position> 紧跟 <length>,如 transform-origin)产生解析歧义。
注意: 计算值总是序列化为两个偏移(不带关键字), 因为计算值不保留语法细节。
8.3.3. <position> 的组合
插值 <position> 的定义为独立对每个成分(x, y)插值,并以左上角为基准归一化为 <length-percentage>。
加法 <position> 也是独立对每个成分(x, y)相加,并以左上角为基准归一化为 <length-percentage>。
9. 函数式记法
函数式记法是一种组件值类型, 可以表示更复杂的类型或触发特殊处理。 其语法以函数名开头, 紧接左括号 (即 <function-token>), 后跟参数, 最后右括号结尾。 与关键字一样,函数名ASCII 不区分大小写。括号内可有空白,但不是必须的。 函数可以有多个参数, 参数格式类似 CSS 属性值。 见§ 2.6 函数式记法定义。
注意: 部分旧有函数式记法,如 rgba(),会多余地使用逗号, 但一般情况下逗号只用于分隔列表项, 或避免语法歧义。 如果逗号用于分隔参数,逗号前后空白可有可无。
background : url ( http://www.example.org/image ); color : rgb ( 100 , 200 , 50 ); content : counter ( list-item) ". " ; width : calc ( 50 % -2 em );
下方定义了数学函数。 其他函数式记法在各自模块中定义; 例如 <color> 函数见 [CSS-COLOR-4] 和 [CSS-COLOR-5]。
10. 数学表达式
数学函数 (calc()、clamp()、sin() 等本章定义的函数) 允许用数学表达式书写 CSS 数值。
数学函数表示一种数值, 可以是:
……或<length-percentage> 等混合类型,并可在任何该类型值可用处使用。
10.1. 基础算术:calc()
calc() 函数是一种数学函数,可对数值进行加(+)、减(-)、乘(*)、除(/)和括号内的基础算术运算。
calc() 函数包含一个 计算, 即一串值与运算符交错组成的序列,可用括号分组 (符合 <calc-sum> 语法), 表示采用标准运算符优先级规则 (* 与 / 优先于 + 与 -,其余左到右)求值的结果。 calc() 函数表示其内部计算的结果。
计算的组成可为字面值 (如 5px), 其他数学函数, 或其他表达式(如 var()), 只要能求值为有效参数类型(如 <length>)。
数学函数可以组合不同单位的值。 下例作者希望每个 section 的外边框盒占据 1/3 空间, 于是从 100%/3 开始, 再减去元素的边框和外边距。 (box-sizing 可自动处理边框和内边距, 但如要包括外边距,需用 数学函数。)
section{ float : left; margin : 1 em ; border : solid1 px ; width : calc ( 100 % /3 -2 *1 em -2 *1 px ); }
类似地,下例中的渐变色带只在元素的第一个和最后一个 20px 处出现颜色过渡:
.fade{ background-image : linear-gradient ( silver0 % , white20 px , whitecalc ( 100 % -20 px ), silver100 % ); }
数学函数也可用于让数值表达更自然易读, 而不是晦涩的小数。 例如,下例将 font-size 设为正好 35em 填满视口, 保证无论屏幕大小如何,屏幕内容始终大致一样多。
:root{ font-size : calc ( 100 vw /35 ); }
功能上这等价于直接写 font-size: 2.857vw, 但前者意图(即 35em 填满视口)对代码阅读者更清晰, 后者读者须反推 2.857 就是 100/35。
运算符遵循标准数学优先级:calc(2 + 3 * 4) 等于 14,不是 20。
括号可用来调整优先级:calc((2 + 3) * 4) 等于 20。
括号和嵌套 calc() 等价; 上述表达式可写作 calc(calc(2 + 3) * 4)。 这在用 var() 逐步组合值时很有用, 例如:
.aspect-ratio-box{ --ar : calc ( 16 /9 ); --w : calc ( 100 % /3 ); --h : calc ( var ( --w) /var ( --ar)); width : var ( --w); height : var ( --h); }
虽然 --ar 可以直接写作 --ar: (16 / 9);,但 --w 既单独用(在 width)也作为 calc() 组件(在 --h), 所以它也必须用完整 calc() 函数形式。
10.2. 比较函数:min()、max() 和 clamp()
min()、max() 和 clamp() 比较多个计算,返回其中一个的值。
min() 或 max() 函数 包含一个或多个逗号分隔的计算, 分别返回最小(最负)或最大(最正)值。
clamp() 接收三个计算——最小值、中值、最大值——返回中值, 按最小值和最大值裁剪,冲突时优先最小值。 (即 clamp(MIN, VAL, MAX) 等价于 max(MIN, min(VAL, MAX)))。
最小值或最大值 (甚至可两者都用) 可以用关键字 none, 表示该侧不裁剪。 (如 clamp(MIN, VAL, none) 等价于 max(MIN, VAL), clamp(none, VAL, MAX) 等价于 min(VAL, MAX), clamp(none, VAL, none) 等价于 calc(VAL)。)
三者参数计算可为任意 <number>、<dimension> 或 <percentage>, 但类型必须一致,否则函数无效; 结果类型即为一致类型。
min()、max() 和 clamp() 可确保值不超过“安全”极限: 例如用视口单位设置font-size的“响应式字号”时, 仍可设定最小值保证可读性:
.type{ /* 字号为 vw 和 vh 平均数的10倍,但不得小于12px */ font-size:max ( 10 *( 1 vw +1 vh ) /2 , 12 px ); }
注意: 每个参数都可用完整数学表达式,无需嵌套 calc()! 你也可以传多个参数,适用于多重约束。
.type{ /* 字号限定在 12px 和 100px 之间 */ font-size:clamp ( 12 px , 10 *( 1 vw +1 vh ) /2 , 100 px ); }
或者只想限定最小值,允许字号随意变大:
.type{ /* 字号至少 12px */ font-size:clamp ( 12 px , 10 *( 1 vw +1 vh ) /2 , none); }
如需其他裁剪逻辑,可结合 clamp()、min() 或 max():
- 让 MAX 优先生效:
-
clamp(min(MIN, MAX), VAL, MAX)。 若想避免重复 MAX 计算, 可反过来嵌套函数——min(MAX, max(MIN, VAL))。
- 让 MAX 和 MIN“互换”顺序:
-
clamp(min(MIN, MAX), VAL, max(MIN, MAX))。 不幸的是,这没法避免 MIN 和 MAX 重复。
10.3. 分步值函数:round()、mod() 和 rem()
分步值函数 round()、mod() 和 rem(),都会根据另一个“步长值”以不同方式转换给定值。
round(<rounding-strategy>?, A, B?) 函数包含一个可选的舍入策略和两个计算参数A和B,并返回A的值,按照舍入策略对A进行舍入,舍入到最接近A的B的整数倍(可以是大于或小于A)。参数 calculations 可以解析为任何 <number>、<dimension> 或 <percentage>,但必须具有一致类型,否则函数无效;结果的类型将是 一致类型。
如果A恰好等于B的整数倍,round()精确返回A(如果相关,会保留A是0⁻还是0⁺)。 否则,B的两个整数倍可能“最接近”A,lower B 更接近 −∞,upper B 更接近 +∞。以下<rounding-strategy>用于决定如何选择它们:
- nearest
-
选择lower B和upper B中与A绝对差值最小的一个。如果两者差值相等(A正好在两者之间),选择upper B。
- up
-
选择upper B。
- down
-
选择lower B。
- to-zero
-
选择lower B和upper B中与0绝对差值最小的那个。
如果 lower B 为零,则其值为 0⁺;如果 upper B 为零,则其值为 0⁻。
如果省略 <rounding-strategy>,则默认为 nearest。 (即四舍五入到最接近的整数。) 如果A的类型 匹配 <number>, 则B可以省略,默认值为1;否则省略B是无效的。
CSSOM 需要规定其舍入方式,CSS函数默认最好也采用一致的舍入方式。应该使用哪种行为?[Issue #5689]
注意: JavaScript 和其他编程语言有时会将不同的舍入策略分为不同的舍入函数。JS的 Math
等价于CSS的 round(down,
...);JS的 Math
等价于CSS的 round(up, ...);JS的 Math
等价于CSS的 round(to-zero, ...);JS的 Math
等价于CSS的 round(nearest,
...),或直接写 round(...)。
注意: <rounding-strategy> 关键字与 block-step-size 中的关键字一致,行为也相同。 (block-step-size 只是缺少 to-zero;由于块大小始终为非负,to-zero 和 down 是一致的。)
取模函数 mod(A, B) 和 rem(A, B) 也包含两个 计算 参数A与B,并返回A与最接近A的B的整数倍(大于或小于A均可)之间的差值。 参数 calculations 可解析为 <number>、<dimension> 或 <percentage>,但必须有相同的类型,否则函数无效;结果的类型与参数相同,类型为参数类型。
这两个函数非常相似,实际上当两个参数都为正或都为负时,返回结果完全一致:函数值等于A减去能使结果在零与B之间的B的整数倍。(具体来说,区间包含零但不包含B。更精确地说,如果B为正,则区间从0⁺开始,如果B为负,则从0⁻开始。)
类似地,mod(-140deg, -90deg) 的值为 -50deg,因为 -140deg 加上 -90deg * 1 等于 -50deg,这是唯一处于 0deg 和 -90deg 之间的值。
将这些示例用 rem() 计算,结果完全相同。
当A值与B步长符号相反时,这两个函数的行为会不同:mod()(即“模”)依然选择能让结果在零与B之间的B的整数倍(保证结果要么为零,要么与B同号,不与A同号),而rem()(即“余数”)选择让结果在零与-B之间的B的整数倍,避免改变值的符号。
而 rem(-18px, 5px) 的值为 -3px:-18px 加 5px * 3 等于 -3px,它与 -18px 同号,且位于 0px 和 -5px 之间。
同理,mod(140deg, -90deg) 的值为 -40deg(140deg 加 -90deg * 2,落在 0deg 和 -90deg 之间),但 rem(140deg, -90deg) 的值为 50deg。
我应该选择 mod() 还是 rem()?
通常,使用该操作的用户可控制步长值(B),而是在修改未知值A。因此,通常更期望结果在0与B之间,而不管A的符号如何,这时应选择 mod()。
比如,如果作者想知道一个长度是否是偶数或奇数像素,mod(A, 2px) 会返回 0px 或 1px(假设该值本来就是整数像素),与A的正负无关。而 rem(A, 2px),如果A是偶数像素会返回0px,但如果是奇数像素,则会返回1px或-1px,取决于A的正负。
不过,也会有相反的需求,因此提供了 rem() 以满足这些场景。此外,rem() 的行为与JavaScript的
运算符一致,所以如果希望CSS与JS代码完全匹配,rem() 就很有用。
注意: mod() 和 rem() 也可以直接用其它函数定义:mod(A, B) 等同于 calc(A - sign(B)*round(down, A*sign(B), B))(可以理解为B为正时是round(down),B为负时是round(up)),而 rem(A, B) 等同于 calc(A - round(to-zero, A, B))。(但这些表达式并不总能正确处理0⁺和0⁻,因为0⁻的加法语义不是交换的。)
10.3.1. 参数取值范围
在 round(A, B) 中,如果B为0,结果为NaN。如果A和B都为无穷大,结果为NaN。
如果A为无穷大但B为有限值,结果为与A相同的无穷大。
如果A为有限值但B为无穷大,则结果取决于 <rounding-strategy> 以及A的符号:
- nearest
- to-zero
-
如果A为正或0⁺,返回0⁺;否则返回0⁻。
- up
-
如果A为正(非零),返回+∞。如果A为0⁺,返回0⁺。否则返回0⁻。
- down
-
如果A为负(非零),返回−∞。如果A为0⁻,返回0⁻。否则返回0⁺。
在 mod(A, B) 或 rem(A, B) 中,如果B为0,结果为NaN。如果A为无穷大,结果为NaN。
仅在 mod(A, B) 中,如果B为无穷大且A与B符号相反(包括符号相反的零),结果为NaN。
注意: 其他所有“B为无穷大”的情况都是有效的,直接返回A。
10.4. 三角函数:sin()、cos()、tan()、asin()、acos()、atan() 和 atan2()
三角函数——sin()、cos()、tan()、asin()、acos()、atan() 和 atan2(),用于计算各种基本三角关系。
sin(A)、cos(A) 和 tan(A) 函数都包含一个 计算,其值必须为 <number> 或 <angle>,并将其参数值视为弧度来计算其对应的三角函数值。 (即 sin(45deg)、sin(.125turn) 和 sin(3.14159 / 4) 均表示相同的值,大约为 .707。) 它们都表示 <number>,返回类型会与输入 计算 的类型保持一致。sin() 和 cos() 的返回值总在 −1 到 1 之间,而 tan() 的返回值可在 −∞ 到 +∞ 之间。(关于数学函数如何处理∞,详见§ 10.9 类型检查。)
asin(A)、acos(A) 和 atan(A) 是“反”或“反三角”函数,对应其“普通”三角函数的反函数。 它们都包含一个 计算,值必须为 <number>,并计算其对应的反三角函数值,返回值视为弧度数,表示为 <angle>,返回类型与输入 计算 的类型保持一致。 asin() 返回的角度需规范化到 [-90deg, 90deg] 范围内; acos() 返回的角度需在 [0deg, 180deg]; atan() 返回的角度需在 [-90deg, 90deg]。
atan2(A, B) 函数包含两个用逗号分隔的 计算 参数A和B。A和B可为 <number>、<dimension> 或 <percentage>,但必须有一致类型,否则函数无效。该函数返回正X轴与点(B, A)之间的 <angle>,返回类型与输入 计算 的类型保持一致。返回角度必须规范到区间(-180deg, 180deg](即大于-180deg,小于等于180deg)。
注意: atan2(Y, X) 一般等价于 atan(Y / X),但当点的分量可能为负时会给出更准确的答案。atan2(1, -1)(点为(-1, 1))返回 135deg,atan2(-1, 1)(点为(1, -1))返回 -45deg。而 atan(1 / -1) 和 atan(-1 / 1) 都返回-45deg,因为内部计算结果都是-1。
10.4.1. 参数取值范围
在 sin(A)、cos(A) 或 tan(A) 中,如果A为无穷大,结果为NaN。(关于数学函数如何处理NaN,详见§ 10.9 类型检查。)
在 sin(A) 或 tan(A) 中,如果A为0⁻,结果为0⁻。
在 tan(A) 中,如果A为渐近值(如 90deg、270deg
等),数值结果为实现自定。如果实现能精确表示这些输入,应在
的渐近处返回+∞,在
处返回−∞,但实现不要求必须能精确表示这些输入(如果不能,将返回其能表示的最接近输入的正确数值结果)。作者不得依赖 tan() 在这些输入下返回特定值。
为什么这些值是实现自定?
正切函数在其渐近点是不连续的:它在一侧趋向正无穷,在另一侧趋向负无穷,且在渐近点本身没有定义。
此外,实现能否精确表示这些渐近点,取决于内部如何存储和处理角度;以度为单位时这些值很简单(如90deg),但以弧度表示时这些值是超越数(如pi / 2),无法精确表示。因此,即便要定义特定行为也比较困难;如果实现内部用弧度,需要做模糊匹配,才能在输入足够接近渐近点时返回预期结果。
Web 另一主流语言 JavaScript,这些函数只接受弧度,因此也无法精确遇到渐近点(大多数其他语言亦如此)。JS中写代码时也无法依赖这些值的特定行为,CSS的需求也不太可能有本质不同。
对于能精确表示渐近点的实现,建议的行为可以保证与 atan() 函数的互相转换:tan(atan(X)) 和 atan(tan(X)) 都会返回(近似)X。也就是说,在 atan() 的支持输出范围内,函数是连续的。
在 asin(A) 或 acos(A) 中,如果A小于-1或大于1,结果为NaN。
在 acos(A) 中,如果A恰好为1,结果为0。
在 asin(A) 或 atan(A) 中,如果A为0⁻,结果为0⁻。
在 atan(A) 中,如果A为+∞,结果为 90deg;如果A为−∞,结果为 -90deg。
在 atan2(Y, X) 中,下面的表格给出了所有特殊参数组合的结果:
X | |||||||
---|---|---|---|---|---|---|---|
−∞ | -finite | 0⁻ | 0⁺ | +finite | +∞ | ||
Y | −∞ | -135deg | -90deg | -90deg | -90deg | -90deg | -45deg |
-finite | -180deg | (正常) | -90deg | -90deg | (正常) | 0⁻deg | |
0⁻ | -180deg | -180deg | -180deg | 0⁻deg | 0⁻deg | 0⁻deg | |
0⁺ | 180deg | 180deg | 180deg | 0⁺deg | 0⁺deg | 0⁺deg | |
+finite | 180deg | (正常) | 90deg | 90deg | (正常) | 0⁺deg | |
+∞ | 135deg | 90deg | 90deg | 90deg | 90deg | 45deg |
注意: 所有这些行为都旨在与大多数编程语言的“标准”定义一致,尤其是与JS中的实现一致。
10.5. 指数函数:pow()、sqrt()、hypot()、log()、exp()
指数函数——pow()、sqrt()、hypot()、log() 和 exp()——用于计算其参数的各种指数运算。
pow(A, B) 函数包含两个用逗号分隔的 计算参数A和B,两者都必须解析为<number>,返回A的B次幂,结果为 <number>。输入的 计算必须有一致类型,否则函数无效;结果类型为 一致类型。
sqrt(A) 函数包含一个 计算参数,必须解析为<number>,返回该值的平方根,结果为 <number>,返回类型与输入 计算的类型保持一致。(sqrt(X) 与 pow(X, .5) 基本等价,仅在部分错误处理上有区别;sqrt() 是常用函数,因此单独提供。)
hypot(A, …) 函数包含一个或多个用逗号分隔的 计算参数,返回以每个 计算为分量的N维向量的长度。(即其参数平方和的平方根。)参数 calculations 可解析为 <number>、<dimension> 或 <percentage>,但必须有一致类型,否则函数无效;结果类型为 一致类型。
为什么 hypot() 允许带单位的维度值,而 pow() 和 sqrt() 只接受数字?
你可以写出像 hypot(30px, 40px) 这样的表达式,解析结果是 50px,但不能写 sqrt(pow(30px, 2) + pow(40px, 2)),虽然在大多数数学系统中这两者是等价的。
原因有二:一是幂运算的数值精度,二是作者的预期冲突。
首先,数值精度。对于类型要匹配像<length> 这样的CSS产生式,单位的指数必须精确为1。理论上,像 pow(pow(30px, 3), 1/3) 这样的表达式应当能做到:内部 pow(30px, 3) 解析为值27000,类型为 «[ "length" → 3 ]»(即 <length>³),再由 pow(X, 1/3) 开立三次方根,指数乘以1/3,得到 «[ "length" → 1 ]»,匹配 <length>。
在纯数学领域这肯定成立,但在计算机二进制浮点数中,幂运算有时并不能精确抵消,最终可能导致数学函数无效,原因难以跟踪。(例如JS中,计算 Math.
,结果不是30,因为
并非严格等于3/10,而
实际上略大于1。)
强制作者先将值转换为数字再做运算,最后再转回想要的单位,虽然麻烦,但能避免数值精度问题:calc(pow(pow(30px / 1px, 3), 1/3) * 1px) 一定能解析成 <length>,其值即使不是精确30,也会非常接近30,即使精度损失导致幂没能完全抵消。
其次,预期冲突。有些作者希望 pow(30px, 2) 的结果是 900px(见 这个Sass issue),即只对数值平方,单位不变。但这样结果就取决于参数的单位;如果 1em 是 16px,那么 pow(1em, 2) 是 1em,而 pow(16px, 2) 是 256px 或 16em,同样参数实际得到的结果却完全不同!CSS允许值自由规范化,而且更复杂表达式如 pow(2em + 10px, 2) 也很难解释。
同样,强制作者先转数字再转回单位可以回避这些问题;pow(30, 2) 就是 900,作者可自行解释这个值。
而 hypot() 则不存在这些问题。单位的数值精度无需担心,输入输出类型一致。结果也不依赖单位,因为其运算本质如此;hypot(3em, 4em) 和 hypot(48px, 64px) 在 1em 等于 16px 时都得到相同的长度:5em 或 80px。所以允许作者直接在 hypot() 中用带单位的值。
log(A, B?) 函数包含一个或两个 计算(分别为待取对数的值和对数的底,底默认为e),必须解析为<number>,返回A以B为底的对数,结果为 <number>,返回类型与输入 计算类型保持一致。
exp(A) 函数包含一个 计算,必须解析为 <number>,返回 pow(e, A) 的值,结果为 <number>,返回类型与输入 计算类型保持一致。
这些大小可以很容易地写成自定义属性:
:root{ --h6 : calc ( 1 rem *pow ( 1.5 , -1 )); --h5 : calc ( 1 rem *pow ( 1.5 , 0 )); --h4 : calc ( 1 rem *pow ( 1.5 , 1 )); --h3 : calc ( 1 rem *pow ( 1.5 , 2 )); --h2 : calc ( 1 rem *pow ( 1.5 , 3 )); --h1 : calc ( 1 rem *pow ( 1.5 , 4 )); }
...而不是直接写预先计算好的数值如 5.0625rem (即 calc(1rem * pow(1.5, 4)) 的值),这样在样式表中来源不明。
多参数时,它给出以这些值为边长的盒子的主对角线长度。这在与变换相关的场景很有用,比如计算元素在按某个X、Y、Z量平移时实际移动的距离。
例如,hypot(30px, 40px) 结果为 50px,这正是元素经 translate(30px, 40px) 变换后起止位置间的距离。如果作者希望元素随着距离增大而变小(比如做词云),就能用这个距离做缩放因子。
如果想要以10为底(例如统计某值有几位)或以2为底(统计二进制位数),可用 log(X, 10) 或 log(X, 2)。
10.5.1. 参数取值范围
在 pow(A, B) 中,如果A为负且有限,B为有限,B必须是整数,否则结果为NaN。
如果A或B为无穷大或0,结果见下表:
A 是 −∞ | A 是 0⁻ | A 是 0⁺ | A 是 +∞ | |
---|---|---|---|---|
B 是 −有限 | 若B为奇整数为0⁻,否则为0⁺ | 若B为奇整数为−∞,否则为+∞ | +∞ | 0⁺ |
B 是 0 | 始终为1 | |||
B 是 +有限 | 若B为奇整数为−∞,否则为+∞ | 若B为奇整数为0⁻,否则为0⁺ | 0⁺ | +∞ |
A < -1 | A = -1 | -1 < A < 1 | A = 1 | A > 1 | |
---|---|---|---|---|---|
B 是 +∞ | 结果为+∞ | 结果为NaN | 结果为0⁺ | 结果为NaN | 结果为+∞ |
B 是 −∞ | 结果为0⁺ | 结果为NaN | 结果为+∞ | 结果为NaN | 结果为0⁺ |
在 sqrt(A) 中,若A为+∞,结果为+∞。若A为0⁻,结果为0⁻。若A小于0,结果为NaN。
在 hypot(A, …) 中,任一输入为无穷大,结果为+∞。
在 log(A, B) 中,若B为1或负数,B在0到1之间或大于1都有效。结果为NaN。若A为负数,结果为NaN。若A为0⁺或0⁻,结果为−∞。若A为1,结果为0⁺。若A为+∞,结果为+∞。
在 exp(A) 中,若A为+∞,结果为+∞。若A为−∞,结果为0⁺。
(关于§ 10.9 类型检查,以及数学函数如何处理NaN和无穷大,详见该节。)
唯一不同于JS同名函数的地方在于,NaN在所有函数中都是“传染性”的:只要有任意参数为NaN,函数就返回NaN。
JS 行为细节
JS中有两种情况NaN不会“传染”到数学函数:
-
Math
会返回. hypot( Infinity , NaN )
。Infinity -
Math
会返回. pow( NaN , 0 )
。1
逻辑似乎是,只要把NaN替换成任意数,返回值都一样。但JS的 Math
函数其实并不总这样:Math
返回
,不是
;Math
也是如此。
由于这是错误边角情况,JS自身也不一致,NaN 的识别/处理通常在CSS更高层完成,而不是在底层数学函数里,所以CSS选择了更一致的方案:所有函数一律“传染”NaN。
10.6. 符号相关函数:abs()、sign()
符号相关函数——abs() 和 sign()——用于计算参数符号相关的函数。
abs(A) 函数包含一个 计算参数A,返回A的绝对值,类型与输入相同:如果A为正或0⁺,直接返回A,否则为 -1 * A。
sign(A) 函数包含一个 计算参数A,A为负数时返回-1,A为正数时返回+1,A为0⁺时返回0⁺,A为0⁻时返回0⁻。返回类型为<number>,与输入 计算类型保持一致。
注意: 这两个函数操作的都是参数完全化简/解析后的值,乍看可能不直观。特别是像 10% 这样的表达式,解析后可能是正也可能是负,取决于它实际被应用到什么上。例如在 background-position 属性中,如果背景图片大于背景区域,正百分比最终会变成负长度,反之亦然。因此 sign(10%) 可能返回 1、-1,甚至 0(如相对于零长度)。
10.7. 数值关键词
计算中的关键词用于获取难以或无法用字面量表示的值。每个关键词都定义了其值、类型及其解析时机。
10.7.1. 数值常量:e、pi
虽然三角与指数函数已能实现很多复杂的数值运算,但有时仍需手动拼接一些合理的表达式,这些表达式常常包含著名常量,如 e 和 π。
为了避免作者手动输入这些常量的多位数字,部分常量可直接使用:
- e
-
自然对数的底数,约等于2.7182818284590452354。
- pi
-
圆周长与直径的比值,约等于3.1415926535897932。
这两个关键词都是 <number>,在解析时确定值。
注意: 这些关键词只能在计算表达式内使用,如 calc(pow(e, pi) - pi) 或 min(pi, 5, e)。若在计算表达式外使用,则按普通关键词处理:animation-name: pi; 指动画名为"pi";line-height: e; 是无效的(不是 line-height: 2.7,但 line-height: calc(e); 是有效的)。
10.7.2. 奇异数值常量:infinity、-infinity、NaN
当计算或其子树变为无穷大或NaN时,已无法用数值表示。为便于序列化这些奇异值,定义如下数学常量:
- infinity
-
正无穷(+∞)
- -infinity
-
负无穷(−∞)
- NaN
-
值为NaN
这些关键词都是 <number>,在解析时确定值。
与CSS关键词惯例一样,这些关键词ASCII大小写不敏感。因此 calc(InFiNiTy) 也是合法的。但 NaN 必须以此规范大小写序列化。
注意: 这些关键词是 <number>,要得到无限长度,例如需要 calc(infinity * 1px) 这样的表达式。
注意: 这些常量主要是为了让无穷大/NaN值的序列化更简单明了,但也可用来表示“最大可能值”,因为无穷大的值会被裁剪到允许范围。虽然实际这样用不多,但确有需要时,infinity 比随便写一个巨大数字意图更明确。
10.7.3. 数值变量
其它规范可定义可在特定上下文下用于计算的额外关键词。例如,relative color 语法定义了多个颜色通道关键词,表示每个通道的值为 <number>。
定义此类关键词的规范必须为每个关键词定义:
10.8. 语法
数学函数的语法如下:
<calc () > =calc ( <calc-sum>) <min () > =min ( <calc-sum>#) <max () > =max ( <calc-sum>#) <clamp () > =clamp ( [ <calc-sum> | none] , <calc-sum>, [ <calc-sum> | none] ) <round () > =round ( <rounding-strategy>?, <calc-sum>, <calc-sum>?) <mod () > =mod ( <calc-sum>, <calc-sum>) <rem () > =rem ( <calc-sum>, <calc-sum>) <sin () > =sin ( <calc-sum>) <cos () > =cos ( <calc-sum>) <tan () > =tan ( <calc-sum>) <asin () > =asin ( <calc-sum>) <acos () > =acos ( <calc-sum>) <atan () > =atan ( <calc-sum>) <atan2 () > =atan2 ( <calc-sum>, <calc-sum>) <pow () > =pow ( <calc-sum>, <calc-sum>) <sqrt () > =sqrt ( <calc-sum>) <hypot () > =hypot ( <calc-sum>#) <log () > =log ( <calc-sum>, <calc-sum>?) <exp () > =exp ( <calc-sum>) <abs () > =abs ( <calc-sum>) <sign () > =sign ( <calc-sum>) <calc-sum> = <calc-product>[ [ '+' |'-' ] <calc-product>] * <calc-product> = <calc-value>[ [ '*' |'/' ] <calc-value>] * <calc-value> = <number> | <dimension> | <percentage> | <calc-keyword> |( <calc-sum>) <calc-keyword> = e | pi | infinity | -infinity | NaN <rounding-strategy> = nearest | up | down | to-zero
在某些上下文中,可以定义额外的 <calc-keyword> 值为有效值。 (例如,在 relative color 语法中,适当的通道关键字是允许的。)
此外,在 + 和 - 运算符两侧必须有 空白。 (* 和 / 运算符可以不带空白使用。)
上面的一些数学函数对其 <calc-sum> 参数有额外限制。 详见各个函数的定义。
UA 必须至少支持包含 32 个 <calc-value> 项的 计算,以及至少 32 层嵌套(括号或函数)。 对于支持可变参数个数的函数(如 min()),还必须至少支持 32 个参数。 如果一个 计算 项数、参数数或嵌套层数超过支持上限,则必须视为无效。
10.9. 类型检查
数学函数可以有多种类型,比如 <length>、<number> 等,取决于其包含的 计算,详见下文。 它可以用在允许该类型值的任何地方。
此外,解析为 数学函数为 <number> 的,可以用于只接受 <integer> 的地方;值会在解析时四舍五入为最接近的整数。
运算符会形成子表达式,其类型由参数决定。
注意: 之前的规范版本对乘除法参数有限制,避免产生更复杂的中间结果(如 1px * 1em,即 <length>²),并便于在解析时检测除零。本版本已放宽这些限制。
-
在 + 或 - 子表达式处,尝试相加两侧参数的类型。如果失败,整个 计算的类型即为失败。否则,子表达式的类型就是返回的类型。
-
其他为终端值,其类型根据CSS类型决定。(除非另有说明,类型的百分比提示为null。)
- <number>
- <integer>
-
其类型为«[ ]»(空映射)
- <length>
-
其类型为«[ "length" → 1 ]»
- <angle>
-
其类型为«[ "angle" → 1 ]»
- <time>
-
其类型为«[ "time" → 1 ]»
- <frequency>
-
其类型为«[ "frequency" → 1 ]»
- <resolution>
-
其类型为«[ "resolution" → 1 ]»
- <flex>
-
其类型为«[ "flex" → 1 ]»
- <calc-keyword>
-
类型由关键字定义
- <percentage>
-
如果该 数学函数 所处上下文中,<percentage> 是相对于其他类型值解析的 (如 width,<percentage> 相对于 <length>), 且该类型不是 <number>, 则类型为该类型,百分比提示为该类型。
否则,类型为«[ "percent" → 1 ]»。
- 其他
-
该计算类型为失败。
- <number>
- calc()
- abs()
-
其包含的 计算的类型。
- min()
- max()
- clamp()
- hypot()
- round()
- mod()
- rem()
- max()
- asin()
- acos()
- atan()
- atan2()
- acos()
-
«[ "angle" → 1 ]»。
- sign()
- sin()
- cos()
- tan()
- pow()
- sqrt()
- log()
- exp()
- sin()
-
«[ ]»(空映射)。
如果上述类型为失败,则 数学函数 无效。
数学函数 会解析为 <number>、<length>、<angle>、<time>、 <frequency>、<resolution>、<flex> 或 <percentage>,取决于其类型 匹配哪个产生式。(这些类别互斥。) 如果不能 匹配任一项,则 数学函数 无效。
注意: 代数化简不影响 数学函数 或其解析类型的有效性。例如,calc(5px - 5px + 10s) 和 calc(0 * 5px + 10s) 都是无效的,因为尝试将长度与时间相加。
注意: 注意 <percentage> 相对于 <number>(如 opacity)的情况下,是不能与数字“组合”的——opacity: calc(.25 + 25%) 是无效的。允许这样做会给“单位代数”带来很大问题(如允许对<dimension>进行乘除),而且到目前为止没有带来新功能。(比如 opacity: 25% 与 opacity: .25 等价,仅仅是语法转换。)你仍然可以用它们做其他运算,如 opacity: calc(100% / 3); 是有效的。
注意: 因为 <number-token> 总是被解释为 <number> 或 <integer>,“无单位0” <length> 在 数学函数中不支持。即 width: calc(0 + 5px); 是无效的,因为它尝试将 <number> 与 <length> 相加,虽然 width: 0; 和 width: 5px; 都是有效的。
注意: 虽然有少数属性裸 <number> 在 used-value 阶段会变为 <length>(如 line-height 及 tab-size),<number> 在 calc() 中永远不会变成“类长度”。它们始终是 <number>。
注意: 在怪异模式 [QUIRKS] 下,一些本只接受 <length> 的属性也定义为接受 <number>,并将其解释为 px 长度。和无单位零一样,这对 数学函数 的解析和行为无影响,不过解析为 数学函数 为 <number> 的,在怪异模式下可能变为有效(并作为 px 长度解释)。
10.9.1. 无穷大、NaN 与有符号零
数学函数遵循 IEEE-754 语义,意味着它们识别正零和负零、正无穷和负无穷,以及 NaN(非数)。
不过,这些概念只在 计算树 内保留;如果 顶层计算(即未直接嵌套于其他 数学函数中的 数学函数)会产生这些特殊值,则会“屏蔽”为标准可表示值,详见下文。
有符号零(此处记为 0⁺ 或 0⁻)不能在 CSS 中直接书写;0、+0 和 -0 都产生标准“无符号”零,规则上视为正(0⁺)。
有符号零 可通过以下方式产生:
-
负零(0⁻)可由一次乘法或除法产生零且仅有一个负参数时得到(如 -5 * 0 或 1 / -infinity)。
-
0⁻ + 0⁻ 或 0⁻ - 0⁺ 得到 0⁻。其他所有加减运算为零时都得 0⁺。
-
0⁻ 乘除正数(包括 0⁺)得负数(0⁻ 或 −∞),0⁻ 乘除负数得正数。
(换言之,0⁻ 的乘除遵循标准符号规则。)
-
0⁺ 和 0⁻ 比较时,0⁻ 小于 0⁺。如 min(0⁺, 0⁻) 得 0⁻,max(0⁺, 0⁻) 得 0⁺,clamp(0⁺, 0⁻, 1) 得 0⁺。
-
某些 数学函数 的参数组合会产生 0⁻(如 round(-1, infinity))。其他运算为零时都得正零(0⁺)。
无穷大 (此处记为 +∞ 或 −∞) 可通过 数学常量 infinity 和 -infinity 直接书写,也可由一些计算产生:
-
除以零会得到 +∞ 或 −∞,符号按标准规则。
-
加减 ±∞ 得相应无穷大。
-
任意值乘以 ±∞ 得相应无穷大。
-
任意值除以 ±∞ 得零。
注意: 下面 NaN 的产生规则,高于上述无穷大的规则。
无穷大 不会逃逸 顶层计算;会被裁剪到上下文允许的最小或最大值,详见 § 10.12 范围检查。
NaN(即“非数”,not a number) 是某些无定义结果运算的结果。 可通过 数学常量 NaN 直接书写,也可由一些计算产生:
-
零除以零、±∞ 除以 ±∞、0 乘以 ±∞、+∞ 加 −∞、或减去同号无穷大,都会得到 NaN。
这些规则优先于其他所有结果。如 0 / 0 是 NaN,不是 +∞。
-
只要有参数为 NaN,任何运算都得到 NaN。
而 calc(1 / calc(-5 * 0)) 会得到 −∞,与 calc(1 / (-5 * 0)) 一样——内部 calc 得到 0⁻,作为非 顶层计算,原样传递给外层 calc 从而得 −∞。若被屏蔽为无符号零,则会得到 +∞。
10.10. 内部表示
内部表示指的是数学函数的计算树:一个树结构,分支节点为运算符节点,对应于数学函数(如 Min、Cos、Sqrt 等)或计算中的运算符(Sum、Product、Negate 和 Invert,即calc-operator 节点),叶节点为数值(如数字、带单位数、百分比)或可解析为数值类型的非数学函数。
-
丢弃values中的所有<whitespace-token>。
-
若values中的某项为<delim-token>,且值为 "+", "-", "*", "/",则为“运算符”;否则为“值”。
-
收集子节点到 Product 和 Invert 节点中。
对于values中连续由"*"或"/"分隔的值项:
-
将每个 "/" 运算符右侧的值项 rhs 替换为以 rhs 为子节点的 Invert 节点。
-
将整个序列替换为以这些值项为子节点的 Product 节点。
-
-
收集子节点到 Sum 和 Negate 节点中。
-
将每个 "-" 运算符右侧的值项 rhs 替换为以 rhs 为子节点的 Negate 节点。
-
如果values只剩一个项,且为 Product 节点或括号包裹的simple block,用该项替换values。
否则,用以values值项为子节点的 Sum 节点替换values。
-
-
此时 values 是 Sum、Product、Negate、Invert 节点组成的树,叶节点为其它类型的值。处理叶节点:
对values中每个叶节点 leaf:
-
如 leaf 为括号包裹的simple block,用解析其内容后的结果替换该叶节点。
-
-
返回简化计算树的结果。
10.10.1. 简化
内部表示会对数学函数尽可能进行即时简化,采用标准代数化简(如乘法分配、同单位合并等)。
用于非属性上下文(如@font-face描述符)时,数学函数按指定值方式简化。
-
如 root 为数值:
-
如为待解析的百分比且有足够信息,解析为实际数值,并用对应规范单位表达,返回该值。
-
如为非规范单位的带单位数,且有足够信息可转为规范单位,转换并返回。
-
如为可解析的<calc-keyword>,返回其解析结果并简化。
-
否则,返回 root。
-
-
如 root 为其它叶节点(非运算符节点):
-
如有足够信息确定其数值,返回其值,并用规范单位表达。
-
否则,返回 root。
-
-
如 root 为非calc-operator 节点的运算符节点,且所有子节点均为数值,且有足够信息计算该运算,则返回运算结果,并用规范单位表达。
此时若仍有百分比,通常会阻止该节点进一步简化,因为还需其他值解析百分比(否则前面已经被转为具体值)。比如 "min" 操作,因为百分比可能基准为负,比较关系可能变化。
但“原始”百分比(如opacity属性)不需解析基准时,可能不会阻止简化。
-
如 root 为 Min 或 Max 节点,尝试部分简化:
-
遍历root的所有子节点 child:
如 child 为可比较大小的数值,且有其它同单位的数值子节点,则将所有同单位子节点合并为一个值,替换 child,移除其它相关子节点。
-
如 root 只剩一个子节点,返回该子节点,否则返回 root。
-
-
如 root 为 Negate 节点:
-
如其子节点为数值,返回一个相等数值但取反(0 - value)。
-
如其子节点为 Negate 节点,返回子节点的子节点。
-
返回 root。
-
-
如 root 为 Invert 节点:
-
如其子节点为数字(非百分比/维度),返回其倒数。
-
如其子节点为 Invert 节点,返回子节点的子节点。
-
返回 root。
-
-
如 root 为 Sum 节点:
-
将子节点为 Sum 节点的,替换为其子节点。
-
对同单位数值子节点,合并为一个数值节点,单位相同。
(如合并纯数字、百分比、px值等)
-
如只剩一个子节点,返回该节点,否则返回 root。
注意: 零值项不能直接从 Sum 移除,只能与同单位值合并。(因为即便为零,单位有时会影响行为。)
-
-
如 root 为 Product 节点:
10.11. 计算值
计算值指数学函数的计算树,在计算值时利用所有可用信息简化后的结果。(如 em 到 px 比例,某些属性下百分比的解析方式等。)
若百分比在计算值阶段未解析,则在数学函数中同样不解析。例如 calc(100% - 100% + 1px) 结果为 calc(0% + 1px),而不是 1px。如某些属性对百分比有特殊计算规则(如height),则只要含百分比的数学函数都适用该规则。
计算树会在使用值阶段再次简化;利用使用值时的信息,数学函数最终总能简化为单一数值。
因此,background-position 的计算会在 calc() 中保留百分比,而 font-size 会直接算成长度。
鉴于表格单元格和表格元素宽高计算的复杂性,同时混合百分比和非零长度用于表格列、列组、行、行组、单元格宽高的数学表达式(无论自动还是固定布局表),必须视为指定了 auto。
10.12. 范围检查
在数学函数中不会进行解析时的范围检查,因此超出范围的值不会导致声明无效。但顶层计算的结果必须被裁剪到目标上下文允许的范围。裁剪会在计算值阶段尽可能进行,如无法完全简化以检查范围,则在使用值阶段裁剪。(裁剪不会在指定值阶段进行。)
注意: 所有接受 calc() 的上下文都必须定义为闭区间(不是开区间)。
注意: 定义上,±∞ 总在任何属性允许范围之外,会裁剪为最小值或最大值。即使某些属性语法允许用关键字表达无穷大(如 animation-iteration-count),最终也会裁剪 ±∞,因为数学函数不能解析为关键字;属性的数值部分总有最小/最大值。
另外,如数学函数解析为<number>,而用于只接受<integer>的地方,则计算值和使用值同样四舍五入为最接近整数,如同上面的裁剪。
width : calc ( 5 px -10 px ); width : calc ( -5 px ); width : 0 px ;
但注意 width: -5px 不等价于 width: calc(-5px)! 超出范围的值在 calc() 外是语法无效的,会导致整个声明被丢弃。
10.13. 序列化
本节仍在讨论中。
-
如果fn对应的计算树的根节点是数值(数字、百分比或带单位数),且当前要序列化的是计算值或更晚阶段,则将其裁剪到上下文允许的范围(如有必要),按正常方式序列化该值并返回。
-
如果fn表示无穷或NaN值:
-
如果计算树的根节点是数值或calc-operator 节点,令s为字符串 "calc("。否则,令s为根节点名称的小写(如 "sin" 或 "max"),再加一个左括号"("。
-
对根节点的每个子节点,序列化计算树。如结果以 "(" 开头且以 ")" 结尾,去掉这两个字符。将所有结果用", "(逗号加空格)拼接,再追加到s。
-
在s后追加")"(右括号)。
-
返回s。
-
令root为计算树的根节点。
-
如果root是数值或非数学函数,按其常规规则序列化并返回结果。
-
如果root不是 Sum、Negate、Product 或 Invert 节点,则为对应函数序列化数学函数,其子节点作为函数逗号分隔的计算参数,并返回结果。
-
如root为 Negate 节点,令s为字符串 "(-1 * "。序列化其子节点并追加到s。追加")"并返回。
-
如root为 Invert 节点,令s为字符串 "(1 / "。序列化其子节点并追加到s。追加")"并返回。
-
如root为 Sum 节点,令s为字符串 "("。排序 root 的子节点。序列化第一个子节点并追加到s。遍历其余子节点:
-
如child为 Negate 节点,追加" - "到s,再序列化Negate的子节点并追加到s。
-
如child为负数,追加" - "到s,再序列化其相反数并追加。
-
否则,追加" + "到s,再序列化child并追加。
最后追加")"并返回。
-
-
如root为 Product 节点,令s为字符串 "("。排序 root 的子节点。序列化第一个子节点并追加到s。遍历其余子节点:
最后追加")"并返回。
-
令ret为一个空列表。
-
如nodes包含数字,将其移出并加入ret。
-
如nodes包含百分比,将其移出并加入ret。
-
如nodes包含带单位数,将它们移出,按单位ASCII不区分大小写排序,追加到ret。
-
如nodes还有其他项,按原顺序追加到ret。
-
返回ret。
类似 calc(20px + 0%) 会序列化为 calc(0% + 20px),保留两个项(保留零值项很重要,这样 calc() 在过渡过程中某值临时为零时不会突然“变形”,也不必在全为零时“选一个单位”)。
像 calc(20px + 2em) 这样的值,指定值序列化为 calc(2em + 20px)(两个单位在指定值阶段不兼容,按字母排序),计算值如 52px(em 在计算值阶段转为绝对长度,假设 1em = 16px,则合并为 52px,此时会去掉 calc() 包裹)。
用于非属性上下文(如@font-face描述符)时,数学函数按指定值方式简化。
更多序列化信息见[CSSOM]。
10.14. 数学函数的组合
插值数学函数,无论彼此之间还是与数值/其他数值函数之间,定义为 Vresult = calc((1 - p) * VA + p * VB)。(简化后表达式可能进一步缩减。)
加法数学函数,无论彼此之间还是与数值/其他数值函数之间,定义为 Vresult = calc(VA + VB)。(简化后表达式可能进一步缩减。)
附录A:协调型列表属性
某些列表属性具有协调效果:它们的值列表中每一项对应一个独立的效果,各属性列表的相同序号项指向同一个效果。通常这些协调值也可以一起指定为列表型简写属性的单个条目。
典型例子是列表型background-*属性,可以指定多层背景图片。每个用于控制图片尺寸、平铺、定位等的属性,其值列表第N项描述作用于第N个背景图片的效果。
协调型列表属性组会创建一个协调值列表,每一项包含该组内各属性的一个值,这些值共同定义一个效果,如一层背景或一个动画。协调值列表按如下方式组装:
-
协调值列表的长度由某个特定协调型列表属性(协调型列表基准属性)的项数决定。(背景的情况下就是 background-image 属性。)
-
计算值不受此类截断或重复影响。
附录B:IANA相关事项
为 about : invalid
URL 方案注册
本节定义并注册
URL,符合[RFC6694]定义的注册流程。
官方注册记录见 http://www.iana.org/assignments/about-uri-tokens/about-uri-tokens.xhtml。
注册Token | invalid
|
---|---|
预期用途 | URL
用于指向不存在的文档和通用错误条件。当需要URL但默认值不应能被解析为任何类型文档时,可用此URL。
|
联系方式/变更控制 | CSS WG <www-style@w3.org>(代表W3C) |
规范 | CSS Values and Units Module Level 3 |
附录C:怪异长度(Quirky Lengths)
当CSS在怪异模式下被解析时,<quirky-length> 是一种 <length> 类型,仅在以下特定属性中有效:
它不在包含或引用这些属性的属性中有效,比如 background 简写属性,或出现在如 函数式表示法(如 calc())中,除了在 rect() 作为 clip 属性时必须允许。
另外,<quirky-length> 在 <length> 作为受影响属性被 @supports 规则解析时必须有效,但在 CSS.supports()
方法中用于这些属性时不有效。
<quirky-length> 在语法上与 <number-token> 完全相同,且会被解释为值相同的 px 长度。
(换句话说,怪异模式允许受影响属性中的所有 px 长度可以不加单位直接书写,类似于无单位的0长度。)
致谢
首先,编辑们要感谢所有为本规范前一版本做出贡献的人。
其次,我们要感谢 Anthony Frehner、Emilio Cobos Álvarez、Koji Ishii、Noam Rosenthal 和 Xidorn Quan 的意见和建议,这些都改进了第4级规范。
变更记录
近期变更
(本节为自第3级以来的增补的子集。)
自2023年12月18日 WD以来的重大变更:
-
为 clamp() 添加了 none 值。 (Issue 9713)
-
修正类型推断对百分比的处理。 (Issue 10017)
-
恢复 视口百分比长度对 overflow: scroll 的依赖,并新增对 scrollbar-gutter 的依赖,使得这些单位的100%能实际吻合初始包含块。 (Issue 6026)
-
允许当A的类型为 <number> 时在 round() 省略B参数。 (Issue 9668)
自2023年10月27日 WD以来的重大变更:
-
将默认视口百分比单位固定为大视口百分比单位,即便违背了“默认不丢失数据原则”,因为现有互操作性和Web兼容性需求。 (Issue 6452)
-
为CSS语法产生式块约定增加了明确定义。 (Issue 2921)
-
澄清了百分号编码URL的字符编码。 (Issue 9301)
自2023年4月6日 WD以来的重大变更:
-
将 mix() 移到 [css-values-5]。 (Issue 9343)
-
颜色类型被定义为不可加性。 (Issue 8576)
-
非属性上下文把数学函数当作指定值处理。 (Issue 7964)
-
规定CSS的URL总是以UTF-8传输。 (Issue 9301)
-
修正加法与累加在不可加/不可累加时用第二个值。 (Issue 9070)
-
规定字体相关长度在用在 font-* 属性时总是相对于父元素解析。 (Issue 8169)
-
单参数 min() 和 max() 会被简化掉。 (Issue 9559)
自2022年10月19日 WD以来的重大变更:
- 增加了 § 2.6 函数式表示法定义,正式定义函数式表示法语法的定义方式。 (Issue 2921)
- 增加了边框宽度取整算法,以反映渲染一致描边宽度的互操作规则。 (Issue 5210)
- 澄清了 mix() 的语法和计算值。 (Issue 8096)
- 未定义 tan() 在渐近值处的行为。 (Issue 8527)
- 规定 <resolution> 的负值本质上是超出范围的。 (Issue 8532)
- 澄清 mix() 完全省略参数时也是有效的。 (Issue 8556)
- 澄清范围裁剪仅针对顶层计算(而非“表达式”)。 (Issue 8158)
- 为 <url()> 和 <src()>(以及 <url>)增加了正式定义。
- 将仅片段URL表述为树作用域引用。 (Issue 3320)
自2021年12月16日 WD以来的重大变更:
- 更改 url() 带 local url flag 时的解析为指向当前节点树(无论文档基础URL如何变更)。 (Issue 3320)
- 将逃逸NaN 的数学函数裁剪结果由无穷大改为零。 (Issue 7067)
- 增加 附录A:协调型列表属性,便于引用此属性模式。 (Issue 7164)
- 限制 mix() 只能作为声明的唯一值。 (Issue 6700)
- 更新以匹配最新 Fetch 术语。 (Fetch PR 1413, CSS PR 7160)
- 澄清字体相关长度的计算不涉及文本整形。
- 定义空url序列化为
。 (Issue 6447)url ( "" ) - 定义 <position> 指定值 的序列化。 (Issue 2274)
- 修正数字定义,允许十进制与科学记数法组合,如原意及 [CSS-SYNTAX-3]所定义。 (Issue 7248)
- 修正多函数返回 type 时应为空映射而非 «[ "number" → 1 ]»。 (Issue 7486)
- 澄清UA限制对line-height对 lh 与 rlh 的影响。 (Issue 3257)
- 定义
<
表示函数式表示法。 (Issue 5728)function () >
自2021年10月16日 WD以来的变更:
- 将 *vi 和 *vb 单位解析为元素自身的书写模式。 (Issue 6873)
- 增加 § 4.5.4 URL处理模型,定义与CORS等集成。 (Issue 562)
-
修正 视口百分比长度 行为分配A与B类型时的颠倒。
-
界面因滚动或其他频繁交互导致变化时,如会引起大幅布局变化而影响用户体验,必须归类为
前者(A)后者(B) 。 -
界面变化有较稳定状态,重排文档有益时,必须归类为
后者(B)前者(A) 。
-
界面因滚动或其他频繁交互导致变化时,如会引起大幅布局变化而影响用户体验,必须归类为
- 规定 calc() 的最小项数、参数数和嵌套层数为32。 (Issue 3462)
- 规定 mod(-0, infinity) 返回 NaN。 (Issue 4723)
- 推迟 toggle() 和 attr() 到第5级。
自2021年9月30日 WD以来的变更:
- 新增 rex、rcap、rch、ric 单位。
- 将 toggle() 改为用分号,统一 mix()。 (Issue 6701)
- 修正 calc() 定义中的措辞问题。 (Issue 6506)
- 引入 <quirky-length> 定义自 [QUIRKS]。 (Issue 6100)
自2021年7月15日 WD以来的变更:
- 为插值值提供了mix()记法。
- 泛化定义了 <integer>、<number>、<percentage>、<length> 的计算。
- 澄清只有非零长度才会产生“百分比+长度”混合,导致表格单元格切换为 auto 尺寸。
自2020年11月11日 WD以来的变更:
- 颜色插值改为引用 [CSS-COLOR-4] 而不是 [CSS-COLOR-3]。
- 增加 svh、svw、svi、svb、svmin、svmax 小视口百分比单位;lvh、lvw、lvi、lvb、lvmin、lvmax 大视口百分比单位;dvh、dvw、dvi、dvb、dvmin、dvmax 动态视口百分比单位。 (Issue 4329 和 Issue 6113)
- 将过大的 <angle> 值裁剪为 360deg 的倍数。 (Issue 6105)
- 恢复组合值的范围检查规则,此前在迁移自CSS Transitions规范时遗漏。 (Issue 6097)
- 规定UA强制最小字体大小应用于实际使用的 font-size,而不是用于解析字体相关长度。 (Issue 5858)
- 澄清 min() 和 max() 的百分比可以部分简化。 (Issue 6293)
自第3级以来的增补
自CSS Values and Units Level 3以来变更:
- 明确未定义数值精度/范围。
- 按值类型增加插值规则,并澄清其计算值。
- 颜色插值引用 [CSS-COLOR-4]。
自CSS Values and Units Level 3以来的增补:
- 定义了 <dashed-ident> 类型。
- 定义了 <ratio> 类型。
- 为 src() 增加到 <url> 类型。
- 增加 vi、vb、ic、cap、lh 和 rlh 长度单位。
- 增加 svh、svw、svi、svb、svmin、svmax 小视口百分比单位 以及 dvh、dvw、dvi、dvb、dvmin、dvmax 动态视口百分比单位。
- 为 x 增加为 dppx 的别名。
- 增加 min()、max()、clamp() 比较函数。
- 增加 round()、mod()、rem()、sin()、cos()、tan()、asin()、acos()、atan()、atan2()、pow()、sqrt()、hypot()、log()、exp()、abs()、sign() 数学函数。
- 增加 e、pi、infinity、-infinity、NaN 常量供 calc() 使用。
- 为 calc() 增加单位代数,允许对维度进行乘除运算。
- 在需要 <integer> 的场合,calc() 中的非整数会自动四舍五入为最接近整数。
- 定义了数学函数的序列化。
- 为 协调型列表属性组增加通用定义,便于引用 background 等属性的协调行为。
安全性注意事项
本规范未引入新的安全性注意事项。
本规范定义了 url() 和 src() 函数(<url>),允许CSS发起网络请求。根据它们所用于的特性,这些请求可能暴露用户是否能访问某网络资源,并暴露内容信息(如样式表规则、图片尺寸、字体度量等),还可能通过URL泄露数据。
隐私注意事项
本规范定义了可暴露用户屏幕尺寸的单位(视口百分比长度)、默认字体大小,以及可能暴露部分可用字体信息(字体相关长度)。
本规范定义了 url() 和 src() 函数(<url>),允许CSS发起网络请求。根据其所用特性,这些请求可能暴露用户是否能访问某网络资源,并暴露内容信息(如样式表规则、图片尺寸、字体度量等),也可能通过URL泄露数据。