CSS3 取值與單位模組

From HTML5 Chinese Interest Group Wiki
Jump to: navigation, search

Contents

介紹

每一個 CSS 屬性定義表格的取值欄位可能含有關鍵字、資料型態(以 ‘<’ 和 ‘>’ 括住)與他們之間如何組合的資訊。本規範描述了很多屬性使用的一般資料型態(以 <length> 最為廣泛使用),而其他特定的資料型態(例:spacing-limit )由各模組描述。

模組關係

本模組取代並擴展了 [CSS21] 章節 1.4.2.14.3A.2

取值欄位語法

CSS 各屬性用這裡解釋的語法用來描合法的取值集合。一個屬性的取值可以有一個以上的部件。

取值部件型態

取值部件的型態跟寫法為以下的幾種情形:

  1. 關鍵字取值(例如 ‘auto’、‘disc’ 等等),以字面呈現,沒有引號(例:auto )。
  2. 基本資料型態,以 ‘<’ 和 ‘>’ 括住(例:<length><percentage> 等等)。
  3. 與其他屬性接受相同範圍的值的型態(例:<'border-width'><'background-attachment'> 等等)。在這種情況下,型態名就是(帶有引號)的屬性名。這種型態「不」包含 ‘inherit’ 值。
  4. 不與任一屬性名相同的非終止符。在這種情況下,非終止符的名稱以 ‘<’ 和 ‘>’ 括住,例如:<spacing-limit>。請注意 <border-width><'border-width'> 的區別 ― 後者是 ‘border-width’ 屬性接受的取值,前者需要額外的展開定義。非終止符的展開定義在第一次在該規範使用此終止符的地方的附近。

有些屬性的取值欄位也包含斜線(/)或逗點(,)字面量,這些字面量代表他們相應的 token。

所有 CSS 屬性也接受關鍵字取值 ‘inherit’ 與 ‘initial’ ,不過為了規範的可讀性不將這兩個取值列入各屬性的取值欄位。這兩個關鍵字不能與其他取值部件一起在同一個宣告中使用,這種宣告是不合法的。舉例來說,‘background: url(corner.png) no-repeat, inherit;’ 是不合法的。

取值部件組合子

取值部件可以以下方法組成屬性的值:

  • 以空白相隔的字代表這些字必須以給定的順序出現。
  • 兩個 & 號(&&)分隔兩個以上必須出現的部件,順序任意。
  • 兩槓(||)分隔兩個以上的可選部件 ― 其中一個以上的部件必須出現,順序任意。
  • 一槓(|)分隔兩個以上的選項 ― 恰好必須出現一個部件。
  • 誇號([])用於將部件分組。

空白運算子的優先度高於兩個 & 號,兩個 & 號高於兩槓,兩槓高於一槓。因此,以下兩行等價:

  a b   |   c ||   d &&   e f
[ a b ] | [ c || [ d && [ e f ]]]

取值部件乘子

任何一個型態、關鍵字、群組後面可接著下列修飾符的其中一個:

  • 星號(*)代表前面的型態、字、群組出現零次以上。
  • 加號(+)代表前面的型態、字、群組出現一次以上。
  • 問號(?)代表前面的型態、字、群組是可選的。
  • 一對在大誇號裡的數字({A,B})代表前面的型態、字、群組出現 A 次以上 B 次以下。
  • 井號(#)代表前面的型態、字、群組出現一次以上,以逗號 token 隔開。

對於可能重複的取值部件(以 ‘*’、‘+’ 或 ‘#’ 表示),使用者代理必須支援至少 20 個重複的部件出現的情形。若一個屬性的取值含有超過支援數量的重複數,使用者代理必須將該宣告視為不合法並無視該宣告。

取值部件與空白

取值部件的設值方式可看成以 [CSS21] 第四章所描述的 token 進行。就如同 CSS 文法語法允許 value 產生式的各部份的 token 以空白隔開,空白也可出現在屬性值的 token 之間。

注:在很多情況下,為了區隔各 token,token 之間的空白是「必要的」。舉例來說,取值 ‘1em2em’ 會被解析成帶有數字 ‘1’ 與不合法的單位 ‘em2em’ 的單個 DIMEN token。在這種情況下,‘2’ 之前的空白是必要的,以將這個取值解析成 ‘1em’ 與 ‘2em’ 兩個長度。

屬性取值範例

以下是一些屬性跟對應的取值欄位的例子。

屬性取值欄位取值範例
orphans<integer>3
text-alignleft | right | center | justifycenter
padding-top<length> | <percentage>5%
outline-color<color> | invert#fefefe
text-decorationnone | underline || overline || line-through || blinkoverline underline
font-family<family-name>#"Gill Sans", Futura, sans-serif
border-width[ <length> | thick | medium | thin ]{1,4}2px medium 4px
text-shadow[ inset? && [ <length>{2,4} && <color>? ]]# | none3px 3px rgba(50%, 50%, 50%, 50%), lemonchiffon 0 0 4px inset
voice-pitch<frequency> && absolute | [[ x-low | low | medium | high | x-high ] || [ <frequency> | <semitones> | <percentage> ]]-2st x-low

文字資料型態

標識符是一串符合文法裡 IDENT token 的字符。[CSS21] 標識符不能用引號括住,不然會被解讀成字串。

預定義關鍵字

在取值定义的字段中,预定义关键字以字面量方式呈现。关键字是CSS标识符且在ASCII范围内以大小写不敏感的方式被识别(即[a-z]等同于[A-Z])。

比如,这里是'border-collapse'属性的取值定义:
Value: collapse | separate

这里是一个示例:

table { border-collapse: separate }

CSS维度关键字:'initial'和'inherit'

如上所述,所有的属性都接受'initial'和'inherit'这两个关键字,它们代表了所有CSS属性的通用取值算法。

'initial'关键字在[CSS21]中被定义。

'inherit'关键字代表了其属性被指定的初始值。[CSS3CASCADE]

注:'default'关键字为保留字。

字串 ― ‘<string>’ 型態

字串取值記作 <string>,由一串用雙引號或單引號括住的字符組成,對應到文法裡的 STRING token。[CSS21]

一对双引号内不能再出现一对双引号,除非将内部的双引号转义 (为 "\"" 或 "\22")。单引号的情况也同理需要转义 (为'\或'\27')。
content: "this is a 'string'.";
content: "this is a \"string\".";
content: 'this is a "string".';
content: 'this is a \'string\'.';

出于美观或其它角度考虑,我们可以把长字符串折成多行,但这些折行会被转义为一个反斜杠(\\),随后这些折行会被从字符串中移除。比如,下面两个选择器是完全相同的:

a[title="a not s\
o very long title"] {/*...*/}
a[title="a not so very long title"] {/*...*/}

不难发现这样的话字符串不能直接代表折行,为了做到这一点,我们将折行转义为"\A"。(十六进制的A是折行符(U+000A),但是代表了CSS在一般情况下的折行。)

資源定位符 ― ‘<url>’ 型態

URL 是資源的指標,是具有特殊解析規則函數記號,記作 <url>,對應到文法裡的 URI token。[CSS21]

以下是一个URL用于背景图片的例子:
body { background: url("http://www.example.com/pinkish.gif") }

不写双引号也可以:

body { background: url(http://www.example.com/pinkish.gif) }
注意,在某些CSS语境中,一个URL用<string>来代表比用<url>更好,比如'@import'规则。

一个URL中的小括号,空格,单引号和双引号都必须通过反斜杠来转义,以保证取值结果是一个有效的 URL token。比如'url(open\(parens)'、'url(close\)parens)'。URL还可以依赖其类型,采取URI-escapes的方式转义,如[URI]中描述的'url(open%28parens)'或'url(close%29parens)'。另一方面,这些特殊字符可以在被引号引起来的'url()'标记的字符串中。

为了依赖绝对路径创建模块化的样式表资源,作者们应该使用相对路径。相对路径(定义于[URI])就是完整路径根据一个基本路径进行截取。RFC 3986第三章定义了该过程的正规算法。在CSS样式表中,其基本路径就是文档的来源。

当一个<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一定对应相同的图片。

數值資料型態

属性可以将数字值限定在一个范围内。如果取值超出了被允许的范围,则该声明被视为无效并会被忽略。

尽管实际的能力有限,CSS理论上支持无限精度和广度的所有取值类型。用户代理对范围和精度应该合理的支持程度。

整數 ― ‘<integer>’ 型態

整數值記作 <integer>。一個整數是一個以上從 ‘0’ 到 ‘9’ 的十進位數字,對應文法裡 NUMBER token 的一個子集。整數的前面可有代表其正負號的 ‘-’ 或 ‘+’。

數 ― ‘<number>’ 型態

數值記作 <number>。一個是一個整數,或零個以上的十進位數字接著小數點(.)接著一個以上的十進位數字。數對應到文法裡的 NUMBER token。同整數,數的前面可有代表其正負號的 ‘-’ 或 ‘+’。

百分比 ― ‘<percentage>’ 型態

百分比值記作 <percentage>,由 <number> 接著百分比記號 ‘%’ 組成。百分比對應到文法裡的 PERCENTAGE token。

百分比值永远是相对于另一个值的,比如长度。每个允许百分比值的属性都定义了该百分比的参考值。这个参考值可以是该元素的另一个属性值,也可以是祖先元素的属性值,或是格式化上下文的值(比如包含区块的宽度)。当一个百分比值被设定在根元素上且该百分比值的参考值是一些继承来的属性时,这个百分比值的结果就是该属性值的初始值乘以这个百分数。

距離單位 ― ‘<length>’ 型態

代表距離量度的長度在屬性取值欄位裡記作 <length>。一個長度是一個量度。長度零可用 <number>0’ 表示。(也就是說,長度零的單位標識符是可選的。)

一個量度是指接著一個單位標識符的,對應文法裡的 DIMENSION token。[CSS21] 同關鍵字,單位標識符在 ASCII 範圍內不分大小寫。

属性值可以在特性的范围内限制长度取值。如果取值超出了被允许的范围,则该声明被视为无效且会被忽略。

对于一些允许负长度值的属性,它增加了格式的复杂度且存在一些实现上的局限。如果一个负长度值被允许但无法被支持,则必须将其转换为可以支持的最接近的值。

至于能够支持的长度限度,用户代理必须给出一个明确的值。

长度单位可以分成两类:相对长度和绝对长度。

相对长度

相对长度用于指定相对另一个长度的长度。使用相对单位的样式表更容易离开一个输出环境并适应另一个环境。

相对单位有:

单位 相对于
em 该元素使用的字体大小
ex 该元素使用的字体的x高度
ch 该元素使用的字体中"0"这一图形的宽度
rem 根元素使用的字体大小
vw 视口的宽度
vh 视口的高度
vmin 视口的高度和宽度中的最小值

子元素并不会继承父元素中指定的相对值,他们将继承计算值

字体相对长度:‘em’、‘ex’、‘ch’、‘rem’单位

除了‘rem’(相对于根元素的字体大小)以外,字体相对长度均相对于其作用的元素的字体尺寸。但有一个例外,即当这些长度作为‘font-size’属性本身的值出现时,它们将相对于父元素(如果该元素没有父元素,则相对于‘font’属性的初始值所对应的尺寸)的字体尺寸。

em单位

与其作用的元素的‘font-size’属性的计算值相等。

使用规则:
h1 { line-height: 1.2em }

意味着h1元素的行高比h1元素的字体尺寸大20%。而如果使用:

h1 { font-size: 1.2em }
则表示h1的字体尺寸比h1元素所继承的字体尺寸大20%。

ex单位

与字体中的x高度相等。采用“x高度”这一名称是因为之乡经常等于小写"x"的高度。但是即便那些不包含字符"x"的字体也会定义一个‘ex’值。

有多种途径可以查找一个字体的x高度。有些字体包含了可靠的x高度的尺寸。如果无法找到可靠的字体尺寸,用户代理可以使用一个小写字母的图形的高度来决定x高度。一个可能的启发式方案是,查看小写字符"o"在其基线以下占了多少距离,并在其绑定盒的顶部的基础上减去该值以获得结果。如果不可能决定x高度,或者没有实践性的方案,则必须假定0.5em作为其值。

ch单位

提前在用于渲染的字体中找到字符"0"(数字零,U+0030)的图形,并计算其宽度值,ch单位与该值相等。

rem单位

与根元素的‘font-size’属性的计算值相等。

当用于根元素的‘font-size’属性时,‘rem’单位相对与该属性的初始值。

视口百分比长度:‘vw’、‘vh’、‘vmin’、‘vmax’单位

视口百分比长度是相对于初始化包含区块的尺寸的。当视口的宽高改变时,他们也会进行相应的缩放。

vw单位

相当于初始化包含区块宽度的1%。

在下面的例子中,如果视口的宽度是200mm,则h1元素的字号将会是16mm ((8x200mm)/100)。
h1 { font-size: 8vw; }

vh单位

相当于初始化包含区块高度的1%。

vmin单位

相当于‘vw’和‘vh’之中比较小的那个。

vmax单位

相当于‘vw’和‘vh’之中比较大的那个。

注:页面媒体定义了初始化包含区块如何根据页面宽度的改变而变换。这同样会影响这些单位。

绝对长度:‘cm’、‘mm’、‘in’、‘pt’、‘pc’、‘px’单位

绝对长度单位之间的关系是固定的,它们瞄向了一些物理的测量。在输出环境已知的条件下尤其重要。绝对单位由物理单位(in, cm, mm, pt, pc)和px单位组成:

单位 定义
‘cm’ 厘米
‘mm’ 毫米
‘in’ 英寸; 1in相当于2.54cm
‘px’ 像素; 1px相当于1in的96分之一
‘pt’ 点; 1pt相当于1in的72分之一
‘pc’ 俗称的12点; 1pc相当于12pt
h1 { margin: 0.5in }      /* inches  */
h2 { line-height: 3cm }   /* centimeters */
h3 { word-spacing: 4mm }  /* millimeters */
h4 { font-size: 12pt }    /* points */
h4 { font-size: 1pc }     /* picas */
p  { font-size: 12px }    /* px */

在CSS设备中,这些度量:(i)要么针对物理单位的物理测量,(ii)要么针对像素单位的参照像素。对于打印媒体和类似的高分辨率设备来说,针对的单位应该是标准物理单位中的一个(英寸、厘米等)。对于低分辨率设备和特殊视距的设备来说,我们推荐换用像素单位。同时推荐表示整个设备像素值的像素单位最好接近参考像素。

注:如果针对的单位是像素单位,则物理单位可能不匹配他们的物理测量。另外如果针对的单位是一个物理单位,则像素单位可能不匹配整个设备的像素值。
注:该像素单位和物理单位的定义不同于之前的CSS版本。特别在过去的CSS版本里像素单位和物理单位并没有通过固定的比例向关联:物理单位总是绑定物理测量,像素单位总是匹配参考像素。(之所以做出改变,是因为太多现存的内容依赖96dpi的假设,破坏这个假设就破坏了内容)

参考像素是指在一个像素密度在96dpi的设备,距离阅读者一臂距离时视觉角度上的一像素。通常一臂距离的长度是28英寸,视觉角度是0.0213度。从阅读者看来,一像素相当于0.26毫米(1/96英寸)。

下图展示了一个参考像素的视图距离效果:一个参考像素在阅读距离为71厘米(28英寸)时的结果是0.26毫米,而在阅读距离为3.5米(12英尺)时的结果是1.3毫米。

图:视图距离增大时像素值也随之增大

第二张图展示了一个设备的像素单位的分辨率的效果:一个1像素乘1像素的区域在低分辨率设备下覆盖了一个点(比如,一个典型计算机的显示器),而相同的区域在高分辨率设备下会覆盖16个点(比如打印机)。

图:高分辨率的设备覆盖1像素乘1像素的区域比低分辨率设备需要更多的更多像素值(点)

其他單位

角度:‘<angle>’类型和‘deg’,‘grad’,‘rad’,‘turn’单位

角度取值被表示为<angle>。不同的单位角度标识符如下:

deg

Degrees,每个圆周是360 degrees。

grad

Gradians,也称作gons或grades,每个圆周是400 gradians。

rad

Radians,每个圆周是2π radians。

turn

Turns,每个圆周是1 turn。

比如,一个直角是‘90deg’或‘100grad’或‘0.25turn’或大约‘1.570796326794897rad’。

时间:‘

时间取值被表示为<code><time></code>。其不同的单位标识符如下:

s

秒。

ms

毫秒。1000毫秒为1秒。

不同的属性可以在一定范围内限制时间取值。如果取值超出了被允许的范围,则声明无效且被忽略。

频率:‘<code><frequency></code>’类型和‘Hz’、‘kHz’单位

频率取值被表示为<code><frequency></code>。其不同的单位标识符如下:

Hz

赫兹,它代表了每秒触发的次数

kHz

千赫,它代表了1000赫兹。

比如,当表示音准的时候,200Hz(或200hz)是低音,而6kHz(或6khz)是高音。

分辨率:‘<code><resolution></code>’类型和‘dpi’、‘dpcm’、‘dppx’单位

分辨率取值被表示为<code><resolution></code>。其不同的单位标识符如下:

dpi

每英寸的点数。

dpcm

每厘米的点数。

dppx

每像素的点数。

<code><resolution></code>单位通过定义每个CSS的‘in’、‘cm’或‘px’中包含的点数(dot),标识单个点在图形显示时的尺寸。具体用法可参考媒体查询[MEDIAQ]规范中的‘resolution’章节或[CSS3-IMAGES]规范中定义的‘image-resolution’属性。

注:由于CSS ‘in’和CSS ‘px’中固定的1:96的比例,‘1dppx’相当于‘96dpi’。这对应了CSS中显示图像的默认分辨率:参见‘image-resolution’。
下面@media规则适用了媒体查询[MEDIAQ]来为每像素的设备像素值大于2的设备设定特定的样式:
@media (min-resolution: 2dppx) { ... }

其他地方定義的資料型態

有些資料型態的定義在資料型態自己的模組裡,其中兩個常用的是 <color><image>

顏色 ― ‘<color>’ 型態

資料型態 <color>[CSS21] 定義並由 [CSS3COLOR] 擴展。支援《CSS3 顏色模組》以上的 UA 必須以該模組定義的方法解讀 <color>

圖像 ― ‘<image>’ 型態

這裡定義資料型態 <image> 為與 <url> 等同的資料型態,並由[CSS3IMAGES] 擴展 ― 支援《CSS3 圖像取值與取代元素模組》以上的 UA 必須以該模組定義的方法解讀 <image>

2D 定位 ― ‘<position>’ 型態

這裡定義資料型態 <position>[CSS21] 定義的 <'background-position'> 的等同語法,表示物件區域(例:背景圖片)在定位區域(例:背景定位區域)的位置。[CSS3BG] 擴展<position> ― 支援《CSS3 背景與邊框模組》以上的 UA 必須以該模組定義的方法解讀 <position>

函數記號

有些取值使用函數記號來進行型態轉換或是將取值綁在一起。函數記號的語法是函數的名稱,馬上緊接著左誇號,接著可選的空白,接著記號的參數,接著可選的空白,接著右誇號。若函數接受一個列的參數,則參數以逗號(‘<code>,</code>’ )分隔,逗號的前、後面可以有空白Bug.png

background: url(http://www.example.org/image);
color: rgb(100, 200, 50 );
content: counter(list-item) ". ";
width: calc(50% - 2em);

數學表達式 ― ‘<code>calc()</code>’ 型態

calc() 函數可以用來將有加法(‘<code>+</code>’)、減法(‘<code>-</code>’)、乘法(‘<code>*</code>’)與除法(‘<code>/</code>’)的數學表達式作為取值部件使用。‘<code>calc()</code>’表达式代表了通过标准的优先级规则进行运算的结果。该表达式可以用在任何<code><length></code>, <code><frequency></code>, <code><angle></code>, <code><time></code>, <code><number></code>, or <code><integer></code>的值中。‘<code>calc()</code>’表达式可以是字面量值、‘<code>attr()</code>’或‘<code>calc()</code>’表达式,或之前各种类型的<code><precentage></code>的值。

section {
  float: left;
  margin: 1em; border: solid 1px;
  width: calc(100%/3 - 2*1em - 2*1px);
}
p {
  margin: calc(1rem - 2px) calc(1rem - 1px);
}

下面的例子将设置‘font-size’,以便视口始终适应显示40个字,以保证文本内容在任何屏幕尺寸下都显示接近的字数。

:root {
    font-size: calc(100vw / 40);
}

如果其它设计都是基于‘rem’单位的,则整个布局将会根据视口宽度做等比例缩放。

下面的例子堆积了两个居中的背景图片,且两张图略有错位。

.foo {
    background: url(top.png), url(bottom.png);
    background-repeat: no-repeat;
    background-position: calc(50% + 20px) calc(50% + 20px), 50% 50%;
}

下面的例子展示了如何在一个渐变中设置两个color-stops,其为到两边的距离相同。

.foo {
    background-image: linear-gradient(to right, silver, 
                                                white 50px, 
                                               white calc(100% - 50px), 
                                               silver);
}

语法

下面的文法與規範內容描述了這些函數的表達語言。

math calc S*;
calc "calc(" S* sum S* ")";
sum product [ S+ [ "+" | "-" ] S+ product ]*;
product unit [ S* [ "*" S* unit | "/" S* NUMBER ] ]*;
attr "attr(" S* wqname [ S+ type-keyword ]? S* [ "," [ unit | calc ] S* ]? ")";
unit [ NUMBER | DIMENSION | PERCENTAGE | "(" S* sum S* ")" | calc | attr ];
注:注意到文法要求二元運算子 ‘<code>+</code>’ 和 ‘<code>-</code>’ 的周圍有空白,但是對 ‘<code>*</code>’ 和 ‘<code>/</code>’沒有這個要求。

另外,下面重定义了CSS2.1附录G中的非正式语法:

term
  : unary_operator?
    [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* |
      TIME S* | FREQ S* ]
  | STRING S* | IDENT S* | URI S* | hexcolor | function

用户代理必须支持‘<code>calc()</code>’的表达式至少20“条”,每一条是一个数字、度量或百分数。如果一个‘<code>calc()</code>’表达式包含的条数比支持的条数更多,则必须以无效对待。

类型检测

每个数学表达式都有一个解析类型,范围是<code><length></code>, <code><frequency></code>, <code><angle></code>, <code><time></code>, <code><number></code>, 或<code><integer></code>。解析类型必须是表达式的有效值;否则,表达式为无效。表达式的解析类型取决于其包含的取值类型。NUMBER token是<code><number></code>或<code><integer></code>类型的。DIMENSION token的配型是根据其单位的(‘cm’是<code><length></code>的,‘deg’是<code><angle></code>的,等等)。一个‘<code>attr()</code>’表达式的类型是取决于其<code><type-or-unit></code>参数的。如果表达式语境中运行百分比,则PERCENTAGE token具有其百分比相对的值的类型;否则一个包含百分比的数学表达式是无效的。

子表达式中的运算符,会基于其参数获得类型。为了让表达式更简单,运算符对可以接受的类型有严格的限制。每个运算符的左右参数类型都会根据不同的限制进行检测。如果兼容的话,类型会根据下面的描述进行解析(为了简化描述,这里忽略了运算符的优先级规则):

  • 对于‘,’, ‘+’, 或 ‘-’运算符,检测两侧类型是否相同,或一侧是<code><number></code>另一侧是<code><integer></code>。如果两侧类型相同,则按该类型解析。如果一侧是<code><number></code>另一侧是<code><integer></code>,则按<code><number></code>类型进行解析。
  • 对于‘*’运算符,检测是否至少一侧的参数是<code><number></code>。如果两侧都是<code><integer></code>,则解析为<code><integer></code>。否则解析为另一侧的类型。
  • 对于‘/’运算符,检测右侧是否是<code><number></code>。如果左侧是<code><integer></code>,则解析为<code><number></code>类型。否则,解析为左侧的类型。

如果一个运算符没有通过上述检测,则该表达式为无效。同时,0作除数也是无效的。这同时包含了用字面量0或计算结果为0的情况(以为纯数字表达式在解析时不能排除任何额外的信息进行评估)。

注:代数简化并不影响‘<code>calc()</code>’表达式的有效性验证或解析类型。比如‘<code>calc(5px - 5px + 10s)</code>’或‘<code>calc(0 * 5px + 10s)</code>’在尝试和长度或时间相加时都是无效的。

计算值

‘<code>calc()</code>’表达式的计算值是在运算符两边类型相同的情况下,根据其所有组件、先解析所有的乘除的子表达式、再解析所有的加减子表达式的结果。

百分比并不解析为计算值,他们并不在‘<code>calc()</code>’表达式中被解析。比如‘<code>calc(100% - 100% + 1em)</code>’解析为‘<code>calc(0% + 1em)</code>’,而不是‘<code>calc(1em)</code>’。如果有一些计算百分比的特殊规则(比如‘<code>height</code>’属性),他们会提供一个包含百分比的‘<code>calc()</code>’表达式。

注:因此,‘<code>calc()</code>’的计算值可以表示为一个数字或一个尺寸和百分比的结合。

对于给定的表格和表格单元格的宽高计算的复杂度来说,数学表达式会针对表格列、表格列组、表格行、表格行组、表格单元格,在自动布局表格和固定布局表格中的‘auto’值处理宽和高中的百分数。

范围检测

表达式的值的结果必须在目标语境被允许的范围内。

注:这要求所有的上下文接受‘<code>calc()</code>’定义封闭范围(非开放范围)内允许的值。
这两行代码都相当于‘<code>width: 0px;</code>’,因为小于0px的值是不被允许的。
width: calc(5px - 10px);
width: 0px;

开关值 ― ‘<code>toggle()</code>

toggle() 表達式允許子嗣元素循環使用一個列裡的值,而不是繼承相同的值。

下面的例子使得<code>em</code>标签在通常情况下为斜体,同时把已被设为斜体的<code>em</code>标签为正常显示。

<code>toggle()</code>’ 表達式的語法為:

toggle( <value># )

其中 <value> 是一個在表達式所處位置合法的 CSS 值。若任何一個裡面的值不合法,則整個 ‘<code>toggle()</code>’ 表達式不合法。

注:因为开关值是被逗号隔开的,所以他们自身不能包含顶级的逗号。

本規範不允許巢狀 ‘<code>toggle()</code>’ 記號,且 ‘<code>toggle()</code>’ 不能包含 ‘<code>attr()</code>’ 或 ‘<code>calc()</code>’ 記號。包含這些構造的宣告不合法。

<code>toggle()</code>’ 回傳的值必須透過比較繼承值 I(一般是父元素的計算值,若對象是根元素的時候,使用屬性的初始值)與 ‘<code>toggle()</code>’ 的第 n 個參數的計算值 Cn 來決定。若 Cn 是滿足 Cn = I 的最前面的值,則 ‘<code>toggle()</code>’ 回傳 Cn+1。不然,若 Cn 是最後的值,又或沒有等於 ICn,則回傳第一個值的計算值。

在巢狀列表中循環使用不同標記,使得頂層是圓盤標記,但在巢狀列表中使用圓標記、正方形標記、盒標記,然後(在第五層深的列表)重複
ul { list-style-type: disk; }
ul ul { list-style-type: toggle(disk, circle, square, box); }
注:注意到 ‘<code>toggle()</code>’ 參考的是父元素的計算值,因此 ‘<code>toggle()</code>’ 就算在非繼承屬性上也有用,就像 ‘<code>inherit</code>’ 關鍵字在非繼承屬性下也有用。
注:属性的计算值是一个绝对的值的集合,而不是一个特殊的序列化[CSS21]。所以,比较计算值应该明确且有预期的结果。比如,一个Level 2 ‘<code>background-position</code>’的计算值有两个偏移值,每个偏移值代表了一个绝对的长度或一个百分比,所以‘<code>background-position: top center</code>’和‘<code>background-position: 50% 0%</code>’的声明是相同的。如果对属性声明的计算值存在含糊不清的定义,请提供反馈,我们可以改进。

屬性參引 ― ‘<code>attr()</code>

attr()函数应用在元素或伪元素的属性中的组件值,并返回其元素的特性值。如果是用在伪元素上的,则取该伪元素源元素的特性值。

‘<code>attr()</code>’表达式的计算值是其元素遵照下面的规定指定的特性的值。

注:在CSS2.1中[CSS21],‘<code>attr()</code>’表达式总是返回字符串,而在CSS3里,‘<code>attr()</code>’表达式可以返回多种不同的类型。不过这不意味着能够返回所有的类型,比如计数器、命名的字符串、引号、或类似‘<code>auto</code>’、‘<code>nowrap</code>’、‘<code>baseline</code>’的关键字。我们有意这样设计,是因为‘<code>attr()</code>’表达式并不是为了在CSS中描述一种展现语言的格式,而是为了进一步得到语义数据。

新的‘<code>attr()</code>’表达是语法是:

attr( <attr-name> <type-or-unit>? [ , <fallback> ]? )

这里的<code><attr-name></code>是一个CSS限定的([CSS3NAMESPACE]中的wqname)代表一个特性名的名称(如果没有命名空间,则它是一个CSS标识符)。

可选的<code><type-or-unit></code>参数是一个用来告诉用户代理如何解释其特性值的关键字,它定义了attr()表达式的类型。关键字取自下面的列表。如果被忽略,则被视为‘<code>string</code>’。

可选的<code><fallback></code>参数代表了一个备选值。如果指定的特性不存在,或该特性值解析失败,或该特性值的解析结果不在该属性的有效范围内。那么这个备选值就会发挥作用。如果备选值不存在,则它会是给定的<code><type-or-unit></code>的默认值。

注:不同于‘<code>toggle()</code>’的<code><value></code>,一个‘<code>attr()</code>’的<code><fallback></code>备选值可以包含顶级的逗号,因为这个备选值一定是最后一个参数。

attr()表达式只在下面情况下有效:

  • attr()表达式的类型在其放置的地方是有效的。
  • 备选值<code><fallback></code>在其attr()表达式放置的地方是有效的。
  • 备选值<code><fallback></code>不包含其它attr()表达式。
  • 如果attr()表达式并不是该属性唯一的组件值,则备选值<code><fallback></code>还必须匹配attr()的类型。
注:如果attr()表达式是整个属性值的话,默认值并不需要是给定的类型。举个例子,如果作者要求的特性值类型是‘<code>px</code>’,则默认值可以是‘<code>auto</code>’,比如‘<code>width: attr(size px, auto);</code>’。 如果attr()是和其它值一起配合使用来凑成一个完整的属性值的,那么默认值必须匹配attr()的类型。比如,‘<code>box-shadow: attr(size px, inset) 5px 10px blue;</code>’是无效的——尽管我们把attr()表达式替换为‘<code>px</code>’长度或‘<code>inset</code>’关键字都是有效的。

如果元素上被指定的特性存在,则特性的取值必须按照<code><type-or-unit></code>参数的方式进行解析。除非类型是‘<code>string</code>’,否则特性值必须首先去掉头尾的空格。处理结果即为该attr()表达式的值。如果特性值无法解析为有效值,则attr()表达式的值为备选值。

<code><type-or-unit></code>的关键字如下:

‘<code>string</code>’
该特性值将会解析为一段CSS<code><string></code>的内容。默认为空字符串。
‘<code>color</code>’
该特性值必须解析为一个HASH或IDENT的CSS token,且成功解释为<code><color></code>。默认值是‘<code>currentColor</code>’。
‘<code>url</code>’
该特性值将会解析为一段CSS<code><string></code>的内容。它会解释为‘<code>url()</code>’内引用的一段字符串。默认值是‘<code>about:invalid</code>’,代表一个不存在的文档,并伴随一个通用的错误环境。相对地址必须根据原始元素的地址进行绝对化,他们对于样式表来说并不是相对的。
‘<code>integer</code>’
该特性值必须解析为一个NUMBER的CSS token,并成功解释为<code><integer></code>。默认值是‘<code>0</code>’,如果‘<code>0</code>’在当前属性中是无效,则默认值是该属性的最小值。如果特性值超出了既定范围,则同样使用默认值。
‘<code>number</code>’
该特性值必须解析为一个NUMBER的CSS token,并解释为<code><number></code>。默认值是‘<code>0</code>’,如果‘<code>0</code>’在当前属性中是无效,则默认值是该属性的最小值。如果特性值超出了既定范围,则同样使用默认值。
‘<code>length</code>’、‘<code>angle</code>’、‘<code>time</code>’、‘<code>frequency</code>’
该特性值必须解析为一个DIMENSION的CSS token,并成功解释为既定类型。默认值是‘<code>0</code>’个相应的单位,如果‘<code>0</code>’在当前属性中是无效,则默认值是该属性的最小值。如果特性值超出了既定范围,则同样使用默认值。如果单位是一个相对长度,则它必须计算为一个绝对长度。
‘<code>em</code>’、‘<code>ex</code>’、‘<code>px</code>’、‘<code>rem</code>’、‘<code>vw</code>’、‘<code>vh</code>’、‘<code>vmin</code>’、‘<code>vmax</code>’、‘<code>mm</code>’、‘<code>cm</code>’、‘<code>in</code>’、‘<code>pt</code>’、‘<code>pc</code>’、‘<code>deg</code>’、‘<code>grad</code>’、‘<code>rad</code>’、‘<code>ms</code>’、‘<code>s</code>’、‘<code>Hz</code>’、‘<code>kHz</code>’、‘<code>%</code>’
该特性值必须解析为一个NUMBER的CSS token,并解释为一个相应的度量单位值。默认值是‘<code>0</code>’个相应的单位,如果‘<code>0</code>’在当前属性中是无效,则默认值是该属性的最小值。如果特性值超出了既定范围,则同样使用默认值。如果单位是一个相对长度,则它必须计算为一个绝对长度。
这个例子展示了通过attr()讲一段XML中的数据图形化显示:
<stock>
    <wood length="12"/>
    <wood length="5"/>
    <metal length="19"/>
    <wood length="4"/>
</stock>

stock::before {
    display: block;
    content: "To scale, the lengths of materials in stock are:";
}
stock > * {
    display: block;
    width: attr(length em); /* default 0 */
    height: 1em;
    border: solid thin;
    margin: 0.5em;
}
wood {
    background: orange url(wood.png);
}
metal {
    background: silver url(metal.png);
}
下面的例子都是无效的,它会导致解析时的错误并使相关的声明被忽略。
content: attr(title color); /* 'content' 不接受颜色值 */

content: attr(end-of-quote string, inherit) close-quote; 
/* 这里不允许 'inherit' 值,因为最终结果会是 'inherit close-quote',这是无效的。 */

margin: attr(vertical length) attr(horizontal deg); 
/* deg 单位在这里是无效的 */

color: attr(color); /* 'color' 不接受字符串 */

附录A:IANA注意事项

注册 about:invalid URL方案

本章节按照the about: uri scheme RFC draft的章程定义并注册了 about:invalid URI。

该注册的官方记录可以在 http://www.iana.org/assignments/about-uri-tokens/about-uri-tokens.xml 找到。

Registered Token invalid
Intended Usage The about:invalid URI references a non-existent document with a generic error condition. It can be used when a URI is necessary, but the default value shouldn't be resolveable as any type of document.
Contact/Change controller CSS WG <www-style@w3.org> (on behalf of W3C)
Specification CSS Values and Units Module Level 3

致谢

Comments and suggestions from Giovanni Campagna, Christoph Päper, Keith Rarick, Alex Mogilevsky, Ian Hickson, David Baron, Edward Welbourne, Boris Zbarsky, Björn Höhrmann and Michael Day improved this module.