13 分页媒体

内容

13.1 分页媒体简介

分页媒体(例如,纸,幻灯片,在计算机屏幕上显示的页面等等)与连续媒体的区别是文档的内容分布在一个或者多个不连续的页里。为了处理页面,CSS 2.1描述了怎样给页盒设置页外边距,以及怎样声明分页符

用户代理负责把一个文档的页盒转换到最终渲染文档的真实页(sheet)(纸,幻灯片,屏幕等等)上。通常页盒与页之间都有一对一的关系,但并不总是这样。可能的转换情况包括:

13.2 页盒:@page规则

页盒是一个矩形区域,它包含两块区域:

在CSS 2.1中无法指定页盒的大小

编写者可以在@page规则中指定页盒的外边距。一条@page规则包含关键字"@page",后面跟着一个可选的页选择器,再后面是一个块包含声明和@规则。在@page关键字和页选择器之间,页选择器和块之间允许有可选的注释和空白字符。@page规则中的声明处于页上下文

注意:CSS 2没有可以出现在@page里的@规则,但这种@规则预期在CSS 3中定义

页选择器指定了要应用声明的页面。CSS 2.1中,页选择器可以指定第一页,所有左面的页,或者所有右面的页

对格式错误的声明,格式错误的语句和@page中非法的@规则的处理规则定义在4.2节,还有下列额外规则:当UA预期一个声明或者@规则的开始(即,一个IDENT或者ATKEYWORD token),但发现了一个非预期token时,该token就被认为是格式错误的声明的第一个token。即这种情况下,用格式错误的声明的规则来决定要忽略的token,而不用格式错误的语句的规则

13.2.1 页外边距

CSS 2.1中,只有外边距属性'margin-top''margin-right''margin-bottom''margin-left''margin')适用于页上下文。下图展示了页,页盒和页外边距之间的关系:

Illustration of sheet, page
box, margin, and page area.   [D]

示例:

有个给所有页设置页外边距的简单例子:

@page {
  margin: 3cm;
}

页上下文没有字体的概念,所以不允许'em'和'ex'单位。margin属性的百分比值是相对于页盒尺寸的。对于左右外边距,参照页盒的宽度,而对于上下外边距,就参照页盒的高度。各个CSS 2.1属性相关的所有其它单位都是合法的

由于(可能存在)负margin值(在页盒上或者元素上)或者绝对定位,内容可能跑到页盒外,但这部分内容会被“切掉”—被用户代理,打印机或者是最后的切纸机

13.2.2 页选择器:选择左页,右页和第一页

在打印双面文档时,位于左面和右面的页盒可能有差异。这可以通过两个用于页选择器的CSS伪类来表达

所有页都会被用户代理自动分类为:left或者:right伪类。文档的第一页是:left还是:right取决于根元素的主书写方向。例如,一份主书写方向为从左向右的文档的第一页将是:right页,而一份主书写方向为从右向左的文档的第一页将是:left页。为了显式地强制让一份文档从左面页还是右面页开始打印,编写者可以在第一个生成盒之前插入一个分页符

示例:

@page :left {
  margin-left: 4cm;
  margin-right: 3cm;
}

@page :right {
  margin-left: 3cm;
  margin-right: 4cm;
}

如果已经给左页和右页指定了不同的声明,用户代理必须遵守这些声明,即使用户代理不把这些页盒转换到左页和右页上(例如,一个只支持单面打印的打印机)

编写者也可以用:first伪类给一份文档的第一页指定样式:

示例:

@page { margin: 2cm } /* All margins set to 2cm */

@page :first {
  margin-top: 10cm    /* Top margin on first page 10cm */
}

(上面的)在:left或者:right @page规则中指定的属性重写了那些不带伪类的@page规则中指定的属性。在:first @page规则中指定的属性重写了那些:left或者:right @page规则中指定的属性

如果一个强制结束符出现在第一个生成盒之前,':first'是否适用于该结束符之前的空白页还是该页之后的页,这在CSS 2.1中是未定义的

左页,右页和第一页上的margin声明可能会导致不同的页区宽度。为了简化实现,用户代理可以对左页,右页和第一页应用单页区宽度,此时,应该应用第一页的页区宽度

13.2.3 页盒外的内容

在格式化页模型里的内容时,有些内容可能会跑到当前页盒外。例如,一个'white-space'属性值为'pre'的元素可能会生成一个比页盒宽的盒。再比如,当盒为绝对定位或者相对定位时,它们可能会跑到“不便”(访问)的位置。例如,图片可能被放在页盒的边缘或者页盒下方100,000米的位置

对这种元素的精确格式化超出了本规范的范围。然而,我们推荐编写者和用户代理遵守下列关于页盒外内容的一般性原则:

13.3 分页符

本节描述了CSS 2.1中的分页符。五个属性指定了用户代理可以或者应该在哪里分页,以及在哪个页面(左页还是右页)后续内容应继续(resume)。每次分页都会结束当前页盒里的布局,还会让文档树的其余部分被放置在新页盒里

13.3.1 分页符属性'page-break-before''page-break-after''page-break-inside'

'page-break-before'
Value:  auto | always | avoid | left | right | inherit
Initial:  auto
Applies to:  块级元素(例外见下文)
Inherited:  no
Percentages:  N/A
Media:  visual, paged
Computed value:  与指定值相同
'page-break-after'
Value:  auto | always | avoid | left | right | inherit
Initial:  auto
Applies to:  块级元素(例外见下文)
Inherited:  no
Percentages:  N/A
Media:  visual, paged
Computed value:  与指定值相同
'page-break-inside'
Value:  avoid | auto | inherit
Initial:  auto
Applies to:  块级元素(例外见下文)
Inherited:  no
Percentages:  N/A
Media:  visual, paged
Computed value:  与指定值相同

这些属性值的含义如下:

auto
既不强制也不禁止生成盒之前(之后,内部)的分页符
always
总是强制生成盒之前(之后)有一个分页符
avoid
避免生成盒之前(之后,内部)的分页符
left
强制生成盒之前(之后)有一个或者两个分页符,以便下一页被格式化为左页
right
强制生成盒之前(之后)有一个或者两个分页符,以便下一页被格式化为右页

(与CSS规范)一致的用户代理可以把'left'和'right'值解释成'always'

典型的,一个潜在的分页符位置受父元素的'page-break-inside'属性,前面元素的'page-break-after'属性以及后面元素的'page-break-before'属性的影响。当这些属性值不为'auto'时,'always','left'和'right'值优先于'avoid'

用户代理必须把这些属性应用给根元素的常规流中的块级元素。用户代理还可能会把这些属性应用到其它元素上,例如,'table-row'元素

当一个分页符分割了一个盒时,该盒的外边距,边框和内边距在分割出现的地方没有可视化效果

13.3.2 元素内的分页符'orphans''widows'

'orphans'
Value:  <integer> | inherit
Initial:  2
Applies to:  块容器元素
Inherited:  yes
Percentages:  N/A
Media:  visual, paged
Computed value:  与指定值相同
'widows'
Value:  <integer> | inherit
Initial:  2
Applies to:  块容器元素
Inherited:  yes
Percentages:  N/A
Media:  visual, paged
Computed value:  与指定值相同

'orphans'属性指定了必须要在页面底部的块容器里保留的最小行数。'widows'属性指定了必须要在页面顶部的块容器里保留的最小行数。下面给出如何用它们来控制分页符的示例

只允许正值

关于段落格式化的信息,请查看行框章节

13.3.3 合法的(Allowed)分页符

常规流中,分页符可以出现在下列位置:

  1. 在块级盒之间的垂直外边距中。当非强制的分页符出现在这里时,相关的'margin-top''margin-bottom'属性的应用值被置为'0'。当强制的分页符出现在这里时,相关的'margin-bottom'属性的应用值被置为'0',相关的'margin-top'的应用值可能会被置为'0'或者保留原值
  2. 在一个块容器盒里的行框之间
  3. 在块容器盒的content边与其子级内容的外边(块级子级的外边距边或行内级子级的行框边)之间,如果它们之间存在(非零)间隔的话

注意:预期CSS3将会指定(怎样)在一个强制分页符后面应用相关的'margin-top'(即,不再置为'0')

这些结束符受以下规则的限制:

如果上面的规则无法提供足够的分页位置(breakpoint)来阻止内容从页盒溢出,那么就删掉规则A,B和D,以寻找额外的分页位置

如果分页位置还不够,就把规则C也删掉,以寻找更多的分页位置

13.3.4 强制分页符

如果该处所有元素生成盒的'page-break-after''page-break-before'属性中,至少有一个值为'always','left'或'right'的话,必须都在(1)处放置分页符(不论其它元素值是什么,即便是avoid)

13.3.5 "最佳"分页符

CSS 2.1没有定义必须使用哪一组合法的分页符,CSS 2.1没有禁止用户代理在任何可能的分页点分页,或者完全不分页。但CSS 2.1推荐用户代理遵守下列启发式方法(虽然承认它们有时很矛盾):

示例:

例如,假设样式表含有'orphans: 4','widows: 2',并且当前页面的底部有20行(行框)可用:

现在假设'orphans'为'10','widows'为'20',并且当前页面底部有8行可用:

13.4 页上下文中的层叠

页上下文中的声明遵循层叠,就像常规CSS声明一样

示例:

考虑下例:

@page {
  margin-left: 3cm;
}

@page :left {
  margin-left: 4cm;
}

由于伪类选择器更高的特殊性,左页的左外边距将是'4cm',而所有其它页面(即,右页)将具有'3cm'的左外边距