阅读的文档为:Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification,地址为:https://www.w3.org/TR/2011/REC-CSS2-20110607/。
# CSS 的处理模型
文档中介绍了支持CSS工作的用户代理,它可能时通过以下步骤来处理源文档:
- 解析文档并创建文档树。(文档树是源文档中编码的元素所构成的树状结构)
- 识别目标媒体类型。(下面会有媒体类型的介绍)
-
检索与为目标媒体类型指定的与文档相关联的所有样式表。
- 通过为适用于目标媒体类型的每个属性分配单个值来注释文档树的每一个元素。属性根据级联和继承章节中描述的机制分配值。
- 计算值的一部分取决于适合于目标媒体类型的格式化算法。例如,如果目标媒体是屏幕,则用户代理应用视觉格式化模型。
- 从注释文档树生成一个格式化结构。通常,格式化结构与文档树非常相似,但也可能显著不同,特别是当作者使用伪元素和生成的内容时。首先,格式化结构根本不必是“树形”——结构的性质取决于实现。第二,格式化结构可以包含比文档树更多或更少的信息。例如,如果文档树中的元素具有“显示”属性的“无”值,则该元素将不会在格式化结构中生成任何内容。另一方面,列表元素可以在格式化结构中生成更多信息:列表元素的内容和列表样式信息。
- 将格式化结构转移到目标介质(例如,打印结果,在屏幕上显示它们,将它们呈现为语音等)。
画布(canvas)
备注:这里的“canvas”是在用户代理层面的属于,而不是 html 层面中的 canvas 标签。
画布描述了“渲染格式化结构的空间”。画布对于空间的每个维度是无限的,但是渲染通常发生在画布的有限区域内,由用户代理根据目标介质建立。例如,呈现给屏幕的用户代理通常施加最小宽度,并且基于视口的尺寸选择初始宽度。呈现给页面的用户代理通常施加宽度和高度约束。听觉用户代理可以在音频空间中施加限制,但不能在时间上限制。
# 语法和基本数据类型
文档中详细描述 CSS 的词法与语法,其中语法是使用BNF范式定义的。据说 Webkit 正是使用 Flex 和 Bison 解析器生成器,通过 CSS 语法文件自动创建解析器。
有关 CSS 的值可以接受的数据有:
1 整数和实数
2 长度
长度值的格式是<实数>(有或没有小数点),紧接着是一个单位标识符(例如,px,em等)。在零长度之后,单元标识符是可选的。
长度单位有两种:相对单位和绝对单位。相对长度单位指定相对于另一个长度属性的长度。使用相对单位的样式表可以更容易地从一个输出环境缩放到另一个输出环境。
相对单位有:
- em:相关字体的“font-size”
- ex:相关字体的“x-height”(备注:“x-height”表示字符“x”的高度)
“em”单位等于使用它的元素的“font-size”属性的计算值。例外是当“em”出现在“font-size”属性本身的值时,在这种情况下,它指的是父元素的字体大小。
“ex”单位由元素的第一个可用字体决定。例外是“ex”出现在“font-size”属性的值中,在这种情况下,它指的是父元素的“ex”。
绝对长度单位是固定的。绝对单位包含物理单位(in,cm,mm,pt,pc)和 px 单位。
器件分辨率对像素(px)单位存在影响,1px的面积在高分辨率的器件中可能由多个点覆盖。(备注:移动端 1 px 细线的问题)
3 百分比
百分比值总是相对于另一个值,例如长度。该值可以是相同元素的另一个属性、祖先元素的属性或格式化上下文的值(例如,包含块的宽度)。
4 URL 和 URI
URI值(统一资源标识符),用于在属性值中指定 URI 的函数符号是“url()”。如下:
body { background: url("yellow") }
5 计数器
6 颜色
7 字符串
字符串既可以用双引号编写,也可以用单引号编写。
8 不支持的值
如果UA不支持某个值,则在解析样式表时忽略该值,就好像该值是非法值一样。
# 分配属性值、级联和继承
1 指定的、计算的和实际的值
一旦用户代理解析文档并构建文档树,它就必须为树中的每个元素分配一个允许在目标媒体类型中使用的值。
属性最终的值通过四个步骤来进行计算:规范中定义的值(specified vlaue,指定值),将这个值解析为一个可以用来继承的值(计算后的值,computed value),
2 继承
继承是基于文档树的,文档树中元素的某些属性可以被其子元素继承,每一个 CSS 属性都定义了它能否被继承。
# 媒体类型
样式表最重要的特征之一是,它们指定文档如何呈现在不同的媒体上:屏幕上、纸上、语音合成器、盲文设备等。
某些CSS属性只针对某些媒体而设计(例如,“页面前中断”属性仅适用于分页媒体)。然而,有时,不同媒体类型的样式表可以共享属性,但对该属性需要不同的值。例如,“字体大小”属性对于屏幕和打印介质都是有用的。两种媒体类型不同,对公共属性要求不同的值;文档通常需要在计算机屏幕上比在纸上更大的字体。因此,有必要表示样式表或样式表的一部分适用于某些媒体类型。
# 指定与媒体相关的样式表
目前有两种方法来指定样式表的媒体依赖:
1 从样式表中指定目标介质,使用@media或@import规则。
@import url("fancyfonts.css") screen; @media print { /* style sheet for print goes here */ }
在文档语言中指定目标介质。例如,在HTML 4 中,“link”元素上的“media”属性指定外部样式表的目标媒体:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <HTML> <HEAD> <TITLE>Link to a target medium</TITLE> <LINK REL="stylesheet" TYPE="text/css" MEDIA="print, handheld" HREF="foo.css"> </HEAD> <BODY> <P>The body... </BODY> </HTML>
# 盒子模型
CSS盒子模型(box model)描述为文档树中的元素生成的矩形盒子,并根据视觉格式化模型(visual formatting model)进行布局。
# 视觉格式化模型
1 视觉格式化模型介绍
视觉格式化模型的作用是,指导用户代理如何为可视化媒体处理文档树。
在可视化格式模型中,每一个文档树中得元素都会根据盒子模型来产生零个或多个盒子。这些盒子的布局由以下内容控制:
- 盒子的尺寸和类型
- 定位体系(包括普通流、浮动和绝对定位)
- 文档树中元素之间的关系
- 外部信息(如视口大小,内含图片的固定尺寸等)
视觉格式化模型不指定格式化的所有方面(例如,它不指定字母间隔算法)。
1.1 视口(viewport)
用于连续媒体的用户代理通常为用户提供视窗(屏幕上的窗口或其他观看区域),用户通过该视窗查阅文档。当视口被调整大小时,用户代理可以改变文档的布局。
当视口小于绘制文档画布的区域时,用户代理应该提供滚动机制。每个画布最多有一个视口,但是用户代理可以呈现给多个画布。举个例子就是,浏览器可以打开多个页面,而每个页面最多用一个窗口显示自己。
1.2 包含块(containing block)
很多盒子的定位和尺寸的计算,都取决于一个矩形的边界,这个矩形,被称作是包含块。 一般来说,一个元素生成的盒子会作为它子孙元素的包含块;我们称之为:一个元素盒子为它的子孙元素建造了包含块。可见包含块是一个相对的概念。
值得注意的是,每个盒子的位置都被它的包含块所影响,但是它不会被这个包含的块所限制,它有可能溢出。
9.2 控制盒子的生成
视觉格式化模型的一部分工作就是从文档元素生成盒子。生成的盒子拥有不同类型,并会对视觉格式化模型的处理产生影响。生成盒的类型取决于CSS的“display”属性。
2.1 块级元素和块级盒子
备注:“元素”是源文档层面的东西,“盒子”是视觉格式化模型层面的东西,可以说“元素”被用户代理格式化为“盒子”。
块级元素(block-level elements)
-
当元素的CSS属性
display
为block、
list-item
或table
时,它就是块级元素 -
块级元素视觉上呈现为块,竖直排列
块级盒子(block-level box)
-
块级盒子参与块格式化上下文(block formatting context)
-
每个块级元素至少生成一个块级盒子,称为主要块级盒子(principal block-level box)。一些元素,比如<li>,生成额外的盒子来放置项目符号,这些额外的盒子相对于主要块级盒子进行放置
-
主要块级盒子将包含后代元素生成的盒子及其生成的内容
-
主要块级盒子是可以使用定位方案(position scheme)的盒子
块容器盒子(block container box)
-
块容器盒子描述跟它后代之间的影响
-
一个块级盒子也可能是块容器盒子
-
块容器盒子(block container box)只能包含其它块级盒子,或生成一个行内格式化上下文(inline formatting context),由此只包含行内盒子(备注:结合匿名块盒子来理解)
-
有些块级盒子,比如表格和可替换元素不是块容器盒。相反,一些块容器盒子,比如非替换行内块及非替换表格单元格,不是块级盒子
匿名块盒子(anonymous block box)
为更容易定义格式化,有时候需要添加额外的盒子,这些盒称为匿名盒子。匿名块盒子无法通过浏览器中的审查元素功能来查看,也无法通过 CSS 选择器来操作。
-
不能被 CSS 选择器选中意味着不能用样式表添加样式。这意味着对于可继承属性,继承父元素的值。不可继承属性,取初始值
-
块容器盒要么只包含行内级盒(inline-level box),要么只包含块级盒(block-level box)。但通常文档会同时包含两者。在这种情况下,将创建匿名块盒子来包含相邻的行内级盒
2.2 行内级元素和行内盒子
行内级元素(inline-level elements)
-
当元素的CSS属性 display 为
inline、
inline-block
或inline-table
时,称它为行内级元素 -
视觉上它将内容与其它行内级元素排列为多行。典型的如段落内容,有文本或图片,都是行内级元素
行内级盒子(inline-level boxes)
-
行内级元素生成行内级盒子
-
参与行内格式化上下文(inline formatting context)
-
行内级盒子分为行内盒子和原子行内级盒子
行内盒子(inline boxes)
-
参与生成行内格式化上下文的行内级盒子称为行内盒子
-
所有 display:inline 的非替换元素生成的盒是行内盒子
原子行内级盒(atomic inline-level boxes)
-
不参与生成行内格式化上下文的行内级盒称为原子行内级盒子
-
这些盒子由可替换行内元素,或 display 值为
inline-block
或inline-table
4 普通流
普通流中的盒子属于块格式化上下文或行内格式化上下文。块级盒子参与块格式化上下文。内联盒子参与行内格式化上下文。