【翻译】指定属性值、级联以及继承( Assigning property values, Cascading, and Inheritance)

时间:2020-9-9 作者:admin

本文翻译至《Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification》中的第六章《Assigning property values, Cascading, and Inheritance》。为了使原文更好理解,故添加了一些示例,如有错误,烦请指出。

写在前面

在翻译第六章时,先对第四章《Syntax and basic data types》中的 URLs 和 URIs 做一个翻译,以便于在后面提到这两个术语时有一个大致的概念。

URLs 和 URIs

本规范中的 URI 值(统一资源标识符,请参见[RFC3986],其中包括 URL、URN 等)用“<uri>”表示。用于在属性值中指定 URI 的功能符号为“url()”,如下所示:

body { background: url("http://www.example.com/pinkish.png") }

URI 值的格式为 url(,后面紧随可选的空白,然后是可选的单引号 ‘ 或双引号 ” 字符,然后是 URI 本身,然后是可选的单引号 ‘ 或双引号 ” 字符,后跟可选的空格,最后跟 )。 两个引号字符必须相同。

一个不带引号的示例:

li { list-style: url(http://www.example.com/redball.png) disc }

出现在未加引号的 URI 中的某些字符串,比如括号、空格字符、单引号、双引号,必须使用反斜杠转义,因此最终的 URI 值是一个 URI 符号:(、)。

根据 URI 的类型,也有可能将上述字符写成 URI 转义符(URI-escapes)(那里的“(”转义后等于 “%28”,“)”转义后等于“%29”,等等。),如[RFC3986]所述。

请注意,注释(COMMENT)符号不能出现在其它符号内:因此“url(/x/pic.png)”表示“/x/pic.png”这个 URI,而不是“pic.png”这个 URI。

为了创建不依赖于资源绝对位置的模块化样式表,作者可以使用相对 URI。相对 URI(在[RFC3986]中定义)使用一个基本的 URI 解析成完整 URI。RFC 3986 第五节定义了此过程的规范算法。对于 CSS 样式表,基本 URI 是样式表的 URI,而不是源文档的 URI。

例如,假设以下规则:

body { background: url("yellow") }

位于 URI 指定的样式表中:

www.example.org/style/basic…

源文档的 body 的背景将会被 URI(www.example.org/style/yello…

用户代理在处理无效 URI 或指定不可用资源的 URI 时可能会有所不同。

指定属性值、级联以及继承(Assigning property values, Cascading, and Inheritance)

目录

  • 指定值、计算值和实际值
    • 指定值(Specified values)
      • 计算值(Computed values)
      • 使用值(Used values)
      • 实际值(Actual values)
  • 继承(Inheritance)
    • inherit 值
  • @import 规则
  • 级联(Cascade)
    • 级联顺序(Cascading order)
      • !important 规则
      • 计算选择器的特殊性
      • 非 CSS 隐式呈现属性的优先级(Precedence of non-CSS presentational hints)

1 指定值、计算值和实际值

一旦用户代理(user agent)解析了一个文档(document)并构建文档树(document tree)后,它会为文档树中的每个元素的每个应用于目标媒体类型的属性分配一个值。

属性的最终值是经过四个步骤计算出来的:首先该值是通过规范确定的(指定值),然后解析为一个用于继承的值(计算值),如果有必要还会转换为一个绝对值(使用值),最后根据本地环境的限制进行转换(实际值)。

1.1 指定值

首先,用户代理必须基于以下机制(优先级顺序)来为每个属性分配一个指定值:
1.如果级联结果是一个值,那么就使用它作为指定值。
2.如果这个元素的这个属性是继承的,并且这个元素不是文档树的根元素,那么就使用它的父元素的计算值作为指定值。
3.否则,请使用这个属性的初始值作为指定值。每个属性的初始值会在属性定义时被指定。

1.2 计算值(TODO)

指定值会在级联期间被解析为计算值;例如,URIs 会被解析为绝对值,em 和 ex 会被计算为像素或者是绝对长度。计算一个值不需要用户代理渲染文档。

用户代理不能解析成绝对 URIs 的 URIs 的计算值就是指定值。

确定属性的计算值由属性定义中的关于计算值的行指定。当指定的值为 inherit 时,有关计算值的定义,请参见《inheritance》

就像Applies To定义的那样,即使该属性没有应用到元素上,它的计算值也会存在。但是,某些属性可能会根据某个属性是否应用到了那个元素来定义一个元素的属性的计算值。

1.3 使用值

在不格式化文档的情况下,将尽可能地处理计算值。但是,某些值只能在文档布局时确定。例如,如果将元素的宽度设置为它的包含块的特定百分比,在确定包含块的宽度前,无法确定它的宽度。使用值是采用计算值并将所有剩余依赖项解析为绝对值的结果。

1.4 实际值

使用值原则上是用于渲染的值,但是用户代理可能无法在给定的环境中使用这个值。例如,用户代理可能只能渲染整数像素宽度的边框,因此可能不得不给计算宽度取近似值,否则可能会迫使用户代理使用黑白阴影来代替全彩色。实际值就是某些经过近似计算的使用值。

2 继承

就像上面描述的,在文档树中,一个元素的子元素将会继承父元素的一些属性值。每个属性都会定义它是否可以被继承。

假设这里有一个 H1 元素,它包含一个强调元素(EM):

<H1>The headline <EM>is</EM> important!</H1>

如果没有给 EM 元素指定颜色,那么被强调的“is”将继承它父元素的颜色,因此,如果 H1 元素是蓝色的,那么 EM 元素也将会是蓝色。

当发生继承时,元素将继承计算值。来自父元素的计算值将同时成为子元素的指定值和计算值。

例如,给定以下样式表:

body { font-size: 10pt }
h1 { font-size: 130% }

文档片段:

<BODY>
  <H1>A <EM>large</EM> heading</H1>
</BODY>

H1 元素的 font-size 属性将具有计算值 13pt(130% 乘以 10pt(即父元素的值))。由于继承了 font-size 的计算值,因此 EM 元素也将具有 13pt 的计算值。如果用户代理没有可用的 13pt
的字体,那么 H1 和 EM 的 font-size 的实际值可能是例如 12pt 的值。

请注意,继承将遵循文档树,并且不会被匿名盒子拦截。

2.1 继承值

每个属性可能会有一个 inherit 的级联值,这意味着,对于一个给定的元素,它和它父级元素的同一属性使用相同的指定值。inherit 值可以用来强制值的继承,也可以用于通常不继承的属性。

如果 inherit 值被设置在根元素上,那么这个属性会被分配它的初始值。

在下面的例子中,body 元素上设置了 color 和 background 属性。在所有其它元素上,color 的值将会继承,背景将会是透明的。如果这些样式是用户的样式表中的一部分,那么白色背景、黑色文字将会在文档中强制执行。

body {
  color: black !important; 
  background: white !important;
}

* { 
  color: inherit !important; 
  background: transparent !important;
}

3 @import 规则

@import 规则允许用户从其它样式表中导入样式规则。在 CSS 2.1 中,任何 @import 规则都必须位于所有其它规则之前(@charset 规则(如果存在)除外)。有关何时用户代理需要忽略 @import,请参见《parsing》。关键字 @import 后面必须紧跟要包含的样式表的 URI。字符串也是被允许的,它将会被解析执行为周围包装了 url() 一样。

以下几行的含义相同,说明了 @import 的两种语法(一种带有 url(),一种是光秃秃的字符串):

@import "mystyle.css";
@import url("mystyle.css");

为了避免用户代理可以避免检索不受支持的媒体类型的资源,作者可以指定依赖某些媒体的 @import 规则。这些条件在 URI 之后,用指定的逗号分隔媒体类型来表示。

以下规则说明了如何使 @import 规则与媒体相关:

@import url("fineprint.css") print;
@import url("bluish.css") projection, tv;

在没有指定任何媒体类型的情况下,导入是不受限制的。这和为媒体类型指定为 all 有相同的效果。仅当目标媒体类型与媒体类型列表匹配时,导入才会生效。

如果媒体类型列表中的项目之一是目标媒体类型或者当媒体类型列表为 all 时,目标媒体类型和媒体类型列表匹配。

请注意,媒体类型查询[MEDIAQ]扩展了媒体类型列表的语法和匹配的定义。

当在多个位置导入同一样式表或将其链接到文档时,用户代理必须将每个样式表当做一个独立的样式表一样处理(或者和它们想做的一样)。

4 级联

样式表可能有三个不同的来源:作者、用户和用户代理。

  • 作者:作者根据文档语言的相关约定为源文档指定样式表。例如,在 HTML 中,样式表可以包含在文档或者外部链接中。
  • 用户:用户可以为特定文档指定样式信息。例如,用户可以指定一个包含样式表的文件,或者用户代理可以提供一个生成用户样式表的接口(或者表现得好像它一样)。
  • 用户代理:符合要求的用户代理都会应用一个默认的样式表(或行为就像它们一样)。用户代理的默认样式表应该符合文档语言的一般描述来显示文档语言的元素(例如,对于可视浏览器,HTML 中的 EL 元素使用斜体表示)。有关 HTML 文档的建议默认样式表,请参见《A sample style sheet for HTML》

请注意,用户可以修改影响默认样式表的系统设置(例如,系统颜色)。但是,某些用户代理的实现使得无法更改默认样式表中的值。

这三个来源的样式表将在作用域上发生重叠,并且根据级联关系相互影响。

CSS 级联为每个样式规则分配权重。当应用多个规则时,权重最大的规则优先。

默认情况下,作者样式表中的规则比用户样式表中的规则具有更大的权重。但是,对于 !important 规则,优先级相反。与 UA 的默认样式表中的规则相比,所有用户和作者规则的权重都更大。

4.1 级联顺序

要查找元素/属性组合的值,用户代理必须应用以下排序顺序:

  1. 查找目标媒体类型适用的相关元素和属性的所有声明。如果关联的选择器与所讨论的元素匹配,并且目标媒体类型与包含声明的所有 @media 规则以及样式表的路径上的所有链接上的媒体类型列表相匹配,则声明适用。
  2. 根据重要性(普通或重要)和来源(作者,用户或用户代理)进行排序。以升序排列:
    1. 用户代理声明
    2. 用户普通声明
    3. 作者普通声明
    4. 作者重要声明
    5. 用户重要声明
  3. 按选择器的特异性对具有相同重要性和来源的规则进行排序:特异性越高的选择器将覆盖更通用的选择器。伪元素和伪类分别被当作普通元素和类。
  4. 最后,按指定的顺序排序:如果两个声明的权重,来源和特异性相同,则以后声明的为准。导入的样式表中的声明被视为在样式表本身中的任何声明之前。

除了个别声明的 !important 设置外,此策略还会使作者的样式表比用户的样式表具有更高的权重。 用户代理必须赋予用户关闭特定作者样式表影响的能力,例如通过下拉菜单。符合 UAAG 1.0 检查点 4.14 的要求可满足此条件[UAAG10]。

4.2 !important 规则

CSS 试图在作者样式表和用户样式表之间建立功能平衡。默认情况下,作者样式表中的规则会覆盖用户样式表中的规则(请参阅级联规则 3)。

但是,为了平衡起见,!important 声明(分隔符 ! 和关键字 important 紧随该声明)优先于普通声明。作者和用户样式表都可能包含 !important 声明,并且用户 !important 规则会覆盖作者 !important 规则。此 CSS 功能通过为用户提供特殊要求(大字体,颜色组合等)的控制,提高了文档的可访问性。

将缩写属性(例如 background)声明为 !important 相当于将它的所有子元素声明为 !important。

在以下示例中,用户样式表中的第一条规则包含 !important 声明,该声明将覆盖作者样式表中的相应声明。由于标记为 !important,因此第二个声明优先级也会更高。但是,用户样式表中的第三条规则不是 !important,因此优先级低于作者样式表中的第二条规则(碰巧是在缩写属性上设置样式)。同样,由于第二条规则是 !important,因此第三条作者样式表规则优先级比第二条作者样式表规则低。这表明 !important 声明在作者样式表中也具有功能。

/* From the user's style sheet */
p { text-indent: 1em ! important }
p { font-style: italic ! important }
p { font-size: 18pt }

/* From the author's style sheet */
p { text-indent: 1.5em !important }
p { font: normal 12pt sans-serif !important }
p { font-size: 24pt }
4.3 计算选择器的特异性

选择器的特异性计算如下:

  • 如果声明的来源是 style 属性而不是带有选择器的规则(= a),则计数为 1;否则,则计数为 0(在 HTML 中,元素的 style 属性的值为元素的样式表规则。这些规则没有选择器,因此 a = 1,b = 0,c = 0,d = 0。)
  • 计算选择器中 ID 属性的数量(= b)
  • 计算选择器中其他属性和伪类的数量(= c)
  • 计算选择器中元素名称和伪元素的数量(= d)

特异性仅基于选择器的形式。特别是,即使 id 属性定义为 ID,形式为“[id = p33]”的选择器也被视为属性选择器(a = 0,b = 0,c = 1,d = 0)在原始文件的 DTD 中。

将四个数字 a-b-c-d(在基数较大的数字系统中)连接起来可得出特异性。

一些案例:

*             {}  /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */
li            {}  /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
li:first-line {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul li         {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul ol+li      {}  /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
h1 + *[rel=up]{}  /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */
ul ol li.red  {}  /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */
li.red.level  {}  /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */
#x34y         {}  /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */
style=""          /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */

<HEAD>
  <STYLE type="text/css">
    #x97z { color: red }
  </STYLE>
</HEAD>
<BODY>
  <P ID=x97z style="color: green">
</BODY>

在上面的示例中,P 元素的颜色为绿色。由于级联规则 3,style 属性中的声明将覆盖 STYLE 元素中的声明,因为它具有更高的特异性。

4.4 非 CSS 隐式呈现属性的优先级

UA 可以选择采用 HTML 源文档中的表示属性。如果是这样,则将这些属性转换为对应的 CSS 规则,其特异性等于 0,并且将它们视为在作者样式表的开头插入。因此,它们可能会被后续的样式表规则覆盖。在转换阶段,此策略将使带样式属性更容易与样式表共存。

对于 HTML,不在以下列表中的任何属性都应视为呈现属性:abbr、accept-charset、accept、accesskey、action、alt、archive、axis、charset、checked、cite、class、classid、code、codebase、codetype、colspan、coords、data、datetime、declare、defer、dir、disabled、enctype、for、headers、href、hreflang、http-equiv、id、ismap、label、lang、language、longdesc、maxlength、media、method、multiple、name、nohref、object、onblur、onchange、onclick、ondblclick、onfocus、onkeydown、onkeypress、onkeyup、onload、onload、onmousedown、onmousemove、onmouseout、onmouseover、onmouseup、onreset、onselect、onsubmit、onunload、onunload、profile、prompt、readonly、rel、rev、rowspan、scheme、scope、selected、shape、span、src、standby、start、style、summary、title、type(except on LI, OL and UL elements)、usemap、value、valuetype、version。

对于其他语言,必须将所有基于文档语言的样式都转换为相应的 CSS,并在用户代理级别输入级联,或者像 HTML 表示提示一样,被视为作者级别的规则,特异性为 0,放置在作者样式表的开头。

下面的用户样式表将会覆盖所有文档中 b 元素的 font-weight 和 XML 文档中带有 color 属性的 font 元素的颜色。但是它不会影响到 HTML 文档中带有 color 属性的任何 font 元素的颜色。

b { font-weight: normal; }
font[color] { color: orange; }

然而下面的规则将会覆盖所有文档中的 font 元素的颜色:

font[color] { color: orange ! important; }
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。