Copyright © 2004 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply.
This module describes the page model that partitions a flow into pages. It builds on the CSS3 Box model module and introduces and defines the page model and paged media. It adds functionality for pagination, page margins, headers and footers, image orientation. Finally it extends generated content for the purpose of cross-references with page numbers.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document contains the CSS3 Paged Media Module W3C Candidate Recommendation of 25 February 2004, which has incorporated the disposition of Last Call comments
In order to exit the Candidate Recommendation phase, the following criteria must be satisfied:
A test suite for this specification will be created during the CR period. Detailed implementation requirements and the invitation for participation in the implementation report will be provided in the preliminary implementation report. Implementers are encouraged to provide feedback by 25 August 2004.
Comments and public discussion are to be sent to the mailing list www-style@w3.org (see instructions), which is preferred for discussion of this and other drafts in the Style area.
This document is a working draft of the CSS working group which is part of the style activity (see summary).
Patent disclosures relevant to CSS may be found on the Working Group's public patent disclosure page.
It is inappropriate to use a W3C Candidate Recommendation as reference material or to cite it as other than "work in progress". Its publication does not imply endorsement by the W3C membership.
This CSS3 module depends on the following other CSS3 modules:
Paged media (e.g., paper, transparencies, pages that are displayed on computer screens, etc.) differ from continuous media in that the content of the document is split into one or more discrete pages. To handle pages, CSS3 describes how:
CSS3 defines a page model that specifies how a document is formatted within a rectangular area, called the page box, that has finite width and height. The page box does not necessarily have a one-to-one correspond to the real sheet where the document will ultimately be rendered (paper, transparency, screen etc.). The CSS3 page model specifies formatting within the page box, but it is the user agent's responsibility to transferred the page box to the sheet. Some user agent transfer possibilities that are not addressed by CSS3 include:
Although CSS3 does not specify how user agents transfer page boxes to sheets, it does include certain mechanisms for telling user agents about the page sheet size and orientation. Furthermore, CSS3 assumes that one page box will be transfer to a side of a sheet.
The keywords "MUST", "SHALL", "MUST NOT", "SHALL NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" when used in this document are to be interpreted as described in RFC 2119 [RFC2119]. However, for readability, these words do not appear in all uppercase letters in this specification.
In the page model the document is transferred into one or more page boxes. The properties of a page box are determined by properties within the page context, which is the rule set of the @page rule. As with other boxes, a page box consists of margin, border, padding and content areas. Page boxes differ from other boxes in the following characteristics:
The following terminology and accompanying diagram describe the page model:
Box | Description | Placement |
---|---|---|
|
||
top | a box filling the area defined by the top margin of the page box for compatibility with previous versions of this document ([[!PGMED19990928]], 7.1.1). | |
top-left-corner | a fixed size box filling the area defined by the intersection of the top and left margins of the page box | |
top-left | a variable width box within the area defined by the top margin and adjoining the top-left-corner margin box | |
top-center | a variable width box within the area defined by the top margin, centered on the page area, and between the top-left and top-right margin boxes | |
top-right | a variable width box within the area defined by the top margin and adjoining the top-right-corner margin box | |
top-right-corner | a box filling the area defined by the intersection of the top and right margins of the page box | |
left-top | a variable height box within the area defined by the left margin and adjacent to the bottom of the top-left-corner. | |
left-middle | a variable height box in the area defined by the left margin, centered on the page area, and between the left-top and left-bottom margin boxes. | |
left-bottom | a variable height box within the area defined by the left margin and adjacent to the top of the bottom-left-corner. | |
right-top | a variable height box within the area defined by the right margin and adjacent to the bottom of the top-right-corner. | |
right-middle | a variable height box in the area defined by the right margin, centered on the page area, and between the right-top and right-bottom margin boxes. | |
right-bottom | a variable height box within the area defined by the right margin and adjacent to the top of the bottom-right-corner. | |
bottom | a box filling the area defined by the bottom margin of the page box for compatibility with previous versions of this document ([[!PGMED19990928]], 7.1.1). | |
bottom-left-corner | a box filling the area defined by the intersection of the bottom and left margins of the page box | |
bottom-left | a variable width box within the area defined by the bottom margin and adjoining the bottom-left-corner margin box | |
bottom-center | a variable width box within the area defined by the bottom margin, centered on the page area, and between the bottom-left and bottom-right margin boxes | |
bottom-right | a variable width box within the area defined by the bottom margin and adjoining the bottom-right corner margin box | |
bottom-right-corner | a box filling the area defined by the intersection of the bottom and right margins of the page box |
Pages and their corresponding page layouts have many possible formats. Among the aspects of page layout that can vary are paper size, orientation of the layout with respect to the paper, order of the pages, how the document will be printed, and how the document will be bound. Some of these depend upon factors such as the major writing direction and the media type that are not be specified by this module. The following terminology is used to describe pages and page treatments:
Different parts of the world use different paper sizes. It is a goal of this specification that web content should be adaptable to a range of different sizes without having to write a specific style sheet for each paper size.
However, in some situations it is important that a certain page size achieves a certain style. This proposal describes two ways of achieving this goal: Media Queries [MEDIAQ] allow different style sheets to be applied to different page sizes, and the 'size' property requests that the document is printed on a page which has a certain size. The CSS Working Group specifically welcomes feedback on the need for and feasibility of these features.
By using Media Queries [MEDIAQ], one style sheet can express different stylistic preferences for different page sizes. Consider this example:
/* style sheet for "A4" printing */ @media print and (width: 21cm) and (height: 29.7cm) { @page { margin: 3cm; } } /* style sheet for "letter" printing */ @media print and (width: 8.5in) and (height: 11in) { @page { margin: 1in; } }
In the example above, "A4" sheets are given a "3cm" page margin, and "letter" sheets are given a "1in" page margin.
In Media Queries, the page is always considered to be in Portrait Orientation. That is, it is not necessary to write Media Queries that swap the width and height values to make sure the style sheet is applied.
Name: | size |
Value: | <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ] |
Initial: | auto |
Applies to: | page context |
Inherited: | N/A |
Percentages: | N/A |
Media: | paged |
Computed value: | specified value |
This property specifies the size and orientation of the containing box of the page box. The assumption is that there is only one page box mapped to a page sheet (or one page box mapped to either side of a page sheet) the 'size' property specifies the size of the page sheet.
The size of a page box MAY either be "absolute" (fixed size) or "relative" (scalable, i.e., fitting available sheet sizes). Relative page boxes allow user agents to scale a document and make optimal use of the page size.
Three values for the 'size' property create a relative page box:
In the following example, the outer edges of the page box will align with the page. The percentage value on the 'margin' property is relative to the page size so if the page sheet dimensions are 210mm x 297mm (i.e., A4), the margins are 2.1mm and 2.97mm.
@page { size: auto;/* auto is the initial value */ margin: 10%; }
For example:
@page { size: 8.5in 11in;/* width height */ }
The above example sets the width of the page box to be 8.5in and the height to be 11in. The page box in this example requires a page sheet size of 8.5"x11"; or larger.
A page size can be specified using one of the following media names. This is the equivalent of specifying the '<page-size>' using length values. The definition of the the media names comes from Media Standardized Names [[!PWGMSN]]
For example:
@page { size: A4 landscape; }
The above example sets the width of the page box to be 297mm and the height to be 210mm. The page box in this example requires a page sheet size of 210mm by 297mm,or large.
User agents MAY allow users to control the transfer of the page box to the sheet (e.g., rotating an absolute page box that's being printed). This is outside the scope of this document
If a page box does not fit the page sheet dimensions, the user agent MAY choose to:
The user agent SHOULD consult the user before performing these operations.
When the page box is smaller than the page size, the user agent SHOULD center the page box on the sheet since this will align double-sided pages and avoid accidental loss of information that is printed near the edge of the sheet.
Authors specify dimensions, orientation, margins etc. of a page box within an @page rule. An @page rule consists of the keyword '@page', an OPTIONAL page name followed with no intervening space by an OPTIONAL page pseudo-class and a block of declarations and margin rules (said to be in the page context).
The OPTIONAL page name and OPTIONAL page pseudo-class constitutes the page selector. The page selector specifies for which pages the declarations apply. In CSS3, page selectors MAY designate first page, all left pages, all right pages, or a page with a specific name.
Properties for the page box are specified within a page context.
The syntax for a page selector is a specialization of the generic at-rule and MUST adhere to the following (more strict) grammar:
Each new lexical token are all specializations of the ATKEYWORD lexical token:
PAGE_SYM ::= "@page" TOP_SYM ::= "@top" TOPLEFTCORNER_SYM ::= "@top-left-corner" TOPLEFT_SYM ::= "@top-left" TOPCENTER_SYM ::= "@top-center" TOPRIGHT_SYM ::= "@top-right" TOPRIGHTCORNER_SYM ::= "@top-right-corner" BOTTOM_STYM ::= "@bottom" BOTTOMLEFTCORNER_SYM ::= "@bottom-left-corner" BOTTOMLEFT_SYM ::= "@bottom-left" BOTTOMCENTER_SYM ::= "@bottom-center" BOTTOMRIGHT_SYM ::= "@bottom-right" BOTTOMRIGHTCORNER_SYM ::= "@bottom-right-corner" LEFTTOP_SYM ::= "@left-top" LEFTMIDDLE_SYM ::= "@left-middle" RIGHTBOTTOM_SYM ::= "@right-bottom" RIGHTTOP_SYM ::= "@right-top" RIGHTMIDDLE_SYM ::= "@right-middle" RIGHTBOTTOM_SYM ::= "@right-bottom" page : PAGE_SYM S* IDENT? pseudo_page? S* '{' S* [ declaration | margin ] [ ';' S* [ declaration | margin ]? ]* '}' S* ; pseudo_page : ':' [ "left" | "right" | "first" ] ; margin : margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S* ; margin_sym : TOP_SYM | TOPLEFTCORNER_SYM | TOPLEFT_SYM | TOPCENTER_SYM | TOPRIGHT_SYM | TOPRIGHTCORNER_SYM | BOTTOM_SYM | BOTTOMLEFTCORNER_SYM | BOTTOMLEFT_SYM | BOTTOMCENTER_SYM | BOTTOMRIGHT_SYM | BOTTOMRIGHTCORNER_SYM | LEFTTOP_SYM | LEFTMIDDLE_SYM | LEFTBOTTOM_SYM | RIGHTTOP_SYM | RIGHTMIDDLE_SYM | RIGHTBOTTOM_SYM ;
The following restrictions and relaxations are made to the syntax above:
The following are examples of page selectors (declaration block intentionally left blank)
@page { ... } @page :left { ... } @page :right { ... } @page LandscapeTable { ... } @page CompanyLetterHead:first { ... } @page:first { ... }; /* identifier and pseudo page. */
The following are examples of margin boxes where the declaration blocks are intentionally left blank.
@page { @top { ... } /* defines a header the width of the page */ @bottom { ... } /* footer is the width of the page */ } @page { @top { ... } /* used by UA that doesn't know about @top-left */ @top-left { ... }/* used by UA that does know about @top-left */ @bottom { ... } /* @top-left only eclipses @top } } @page { @top-left { ... /* document name */ } @bottom-center { ... /* page number */} } @page :left { @left-middle { ... /* page number in left margin */ }} @page :right{ @right-middle { ... /* page number in right margins of right pages */}} @page :left { @bottom-left-corner { ... /* left page numbers */ }} @page :right { @bottom-right-corner { ... /* right page numbers */ }} @page :first { @bottom-left-corner { ... /* empty footer on 1st page */ } @bottom-right-corner { ... /* empty footer */ } }
Declarations in the page context obey the cascade just like normal CSS3 declarations.
Properties in an '@page' rule with a page name override those specified in an '@page' rule without a name. Properties specified in a ':left' (or ':right') '@page' rule override those specified in an '@page' rule that has no pseudo-class specified. Properties specified in a ':first' '@page' rule override those specified in ':left' (or ':right') '@page' rules.
Consider the following example:
@page { margin-left: 3cm; } @page :left { margin-left: 4cm; }
Due to the higher specificity of the pseudo-class selector, the left margin on left pages will be '4cm' and all other pages (i.e., the right pages) will have a left margin of '3cm'.
The margin, border and padding properties apply to the page box. They are specified within the page context. They follow the normal rules for box properties with the following exceptions:
When printing double-sided documents, the page boxes on left and right pages MAY be different. This MAY be expressed through CSS pseudo-classes defined in the page context.
All pages are automatically classified by user agents into either the ':left' or ':right' pseudo-class. The following example creates left and right binding edges using these pseudo-classes.
@page :left { margin-left: 3cm; margin-right: 4cm; } @page :right { margin-left: 4cm; margin-right: 3cm; }
If different declarations have been given for left and right pages, the user agent MUST honor these declarations even if the user agent does not transfer the page boxes to left and right sheets (e.g., a printer that only prints single-sided).
Authors MAY also specify style for the first page of a document with the ':first' pseudo-class:
@page { margin: 2cm } /* All margins set to 2cm */ @page :first { margin-top: 10cm /* Top margin on first page 10cm */ }
Whether the first page of a document is ':left' or ':right' depends on the major writing direction of the document and is outside the scope of this document. However, to force a ':left' or ':right' first page, authors MAY insert a page break before the first generated box (e.g., in HTML, specify this for the BODY element).
Note. Adding declarations to the ':left' or ':right' pseudo-class does not influence whether the document comes out of the printer double- or single-sided (which is outside the scope of this specification).
Note. Future versions of CSS may include other page pseudo-classes.
When formatting content in the page model, some content MAY end up outside the page box. For example, an element whose 'white-space' property has the value 'pre' MAY generate a box that is wider than the page box. Also, when boxes are positioned absolutely, they MAY end up in "inconvenient" locations. For example, images MAY be placed on the edge of the page box. Similarly when boxes are positioned fixed they MAY also end up outside of the page box.
A specification for the exact formatting of such elements lies outside the scope of this document. However, we recommend that authors and user agents observe the following general principles concerning content outside the page box:
Margin boxes can be used to create page headers and footers, which are portions of the page set aside for supplementary information such as the page number or document title. The location of page headers and footer is one of the many graphic design choices a document's author makes.
Please note that the margin boxes are oriented with respect to the content and are independent of page orientation, for example the top margin boxes are above the page box in both portrait and landscape orientation.
Margin boxes are created through margin at-rules inside the page context.
A margin at-rule consists of an ATKEYWORD that identifies the margin box (e.g. '@top-left') and a block of declarations (said to be in the margin context).
The following style sheet establishes a page header containing the title ("Hamlet") on the left side and the page number, preceded by "Page ", on the right side:
@page { size: 8.5in 11in; margin: 10%; @top-left { content: "Hamlet"; } @top-right { content: "Page " counter(pages); } }
The maximum potential width and height of each margin box is determined by establishing the containing box for the margin box in the steps shown below. There are two quantities used in the follow calculations:
Calculations:
The maximum widths and heights for the containing boxes discussed above, are the maximum values for the margin boxes. Values of the 'width', 'height', 'padding', 'margin', and 'border' properties for these boxes that result in a value larger than the maximum MUST be ignored from the outside in, that is first the margin, then the border, and so forth. If, after ignoring margin, border, and padding, the width (or height) is too large, the maximum value MUST be used instead. This keeps the margin boxes from intruding into the page area or off the page.
Margin boxes have an initial value of zero for padding, border and margin. The default height of top boxes is the value of page box's top margin. The default height of the bottom boxes is the value of the page box's bottom margin. The initial value for 'content' is 'none'. The initial value of text-align, vertical-align, width and height for margin boxes is defined below:
Margin box | 'text-align' | 'vertical-align' | 'width' | 'height' |
---|---|---|---|---|
|
||||
top | left | middle | width of page sheet | 'margin-top' |
top-left-corner | right | middle | 'margin-left' | 'margin-top' |
top-left | left | middle | if the content is empty AND top-center content is empty then width ← 0 else if then else if top-center content width > 0 then width ← ((max box width × top-center content width) ÷ ∑(top-center content width, 2 × max (top-left content width, top-right content width)) ÷ 2 else if width of top-right = 0 then width ← max box width else width ← (max box width × top-left content width) ÷ ∑(top-left content width, top-right content width) end if |
'margin-top' |
top-center | center | middle | if top-left
content is empty AND top-right content is empty then width ← max box width else width ← (max box width × top-center content width) ÷ ∑(top-center content width, 2 × max (top-left content width, top-right content width) end if |
'margin-top' |
top-right | right | middle | if the content is empty AND top-center content is empty then width ← 0 else if top-center content width > 0 then width ← ((max box width × top-center content width) ÷ ∑(top-center content width, 2 × max (top-left content width, top-right content width)) ÷ 2 else if top-left content width = 0 then width ← max box width else width ← (max box width × top-right content width) ÷ ∑(top-left content width, top-right content width) end if |
'margin-top' |
top-right-corner | left | middle | 'margin-right' | 'margin-top' |
left-top | center | top | 'margin-left' | if the content is empty AND left-middle content is empty then height ← 0 else if left-middle content height > 0 then height ← ((max box height × left-middle content height ) ÷ ∑(left-middle content height , 2 × max (left-top content height , left-bottom content height )) ÷ 2 else if left-bottom content height = 0 then height ← max box height else height ← (max box height × left-top content height) ÷ ∑(left-top content height, left-bottom content height) end if |
left-middle | center | middle | 'margin-left' | if left-top
content is empty AND left-bottom content is empty then height ← max box height else height ← (max box height × left-middle content height ) ÷ ∑(left-middle content height , 2 × max (left-top content height , left-bottom content height ) end if |
left-bottom | center | bottom | 'margin-left' | if the content is empty AND left-middle content is empty then height ← 0 else if left-middle content height > 0 then height ← ((max box height × left-middle content height ) ÷ ∑(left-middle content height , 2 × max (left-top content height, left-bottom content height )) ÷ 2 else if left-top content height = 0 then height ← max box height else height ← (max box height × left-bottom content height) ÷ ∑(left-top content height, left-bottom content height) end if |
right-top | center | top | 'margin-right' | if the content is empty AND right-middle content is empty then height ← 0 else if right-middle content height > 0 then height ← ((max box height × right-middle content height ) ÷ ∑(right-middle content height , 2 × max (right-top content height , right-bottom content height )) ÷ 2 else if right-bottom content height = 0 then height ← max box height else height ← (max box height × right-top content height) ÷ ∑(right-top content height, right-bottom content height ) end if |
right-middle | center | middle | 'margin-right' | if right-top content is empty AND right-bottom content is empty then height ← max box height else height ← (max box height × right-middle content height ) ÷ ∑(right-middle content height , 2 × max (right-top content height , right-bottom content height ) end if |
right-bottom | center | bottom | 'margin-right' | if the content is empty AND right-middle content is empty then height ← 0 else if right-middle content height > 0 then height ← ((max box height × right-middle content height ) ÷ ∑(right-middle content height , 2 × max (right-top content height , right-bottom content height )) ÷ 2 else if right-top content height = 0 then height ← max box height else height ← (max box height × right-bottom content height ) ÷ ∑(right-top content height, right-bottom content height ) end if |
bottom | left | middle | width of page sheet | 'margin-bottom' |
bottom-left-corner | right | middle | 'margin-left' | 'margin-bottom' |
bottom-left | left | middle | if the content is empty AND bottom-center content is empty then width ← 0 else if bottom-center content width > 0 then width ← ((max box width × bottom-center content width) ÷ ∑(bottom-center content width, 2 × max (bottom-left content width, bottom-right content width)) ÷ 2 else if bottom-right content width = 0 then width ← max box width else width ← (max box width × bottom-left content width) ÷ ∑(bottom-left content width, bottom-right content width) end if |
'margin-bottom' |
bottom-center | center | middle | if bottom-left content is empty AND bottom-right content is empty then width ← max box width else width ← (max box width × bottom-center content width) ÷ ∑(bottom-center content width, 2 × max (bottom-left content width, bottom-right content width) end if |
'margin-bottom' |
bottom-right | right | middle | if the content is empty AND bottom-center content is empty then width ← 0 else if bottom-center content width > 0 then width ← ((max box width × bottom-center content width) ÷ ∑(bottom-center content width, 2 × max (bottom-left content width, bottom-right content width)) ÷ 2 else if bottom-left content width = 0 then width ← max box width else width ← (max box width × bottom-right content width) ÷ ∑(bottom-left content width, bottom-right content width) end if |
'margin-bottom' |
bottom-right-corner | left | middle | 'margin-right' | 'margin-bottom' |
The following is a collection of examples of headers.
The following is an example of:
@page { @top-left { content: "Header in Left Cell (top-left)" } }
Because there is no center cell the extent of the top-left is allowed to cross the center.
The following is an example of:
@page { @top-center { content: "Header in Center Cell (top-center)" } }
The following is an example of:
@page { @top-right { content: "Header in Right Cell (top-right)" } }
Because there is no center cell the extent of the top-right is allowed to cross the center.
The following is an example of:
@page { @top-left { content: "Left Cell (top-left)" } @top-center { content: "Header in Center Cell (top-center)" } }
The following is an example of:
@page { @top-center { content: "Header in Center Cell (top-center)" } @top-right { content: "Right Cell (top-right)" } }
The following is an example of:
@page { @top-left { content: "Header in top-left with approx. " "twice as many words as right cell." } @top-right { content: "Right cell (top-right)" } }
Because there is no center cell the extent of the top-left is allowed to cross the center. As the intrinsic width of top-left is approx. twice the intrinsic width of top-right the top-left margin box is approx. twice as wide as the top-right margin box.
A margin box is instantiated if a margin context and one of the following conditions hold:
The example following style sheet could be used to create a top centered header with the current chapter name:
h1 { string-set: chapter content() } @page { margin: 10%; @top-center { content: string(chapter) } }
Both counters and string-sets could be updated many times on a given page. Which value of a string-set or a counter is being referred to in a margin box is specified using the 'page-policy' property in the @string context or @counter context.
h1 { string-set: chapter content() } @string chapter { page-policy: last } @page { margin: %10; @top-center { content: string (chapter) } }
To use the chapter name as it was when the processing of the page started, the designer would specify a 'page-policy' of 'start' instead of 'last'. Designers can also use the value of a string or counter after its first state change on a page by specifying 'first'.
The following sections explain page formatting in CSS3 paged media. Five properties indicate where the user agent MAY or SHOULD break pages, and on what page (left or right) the subsequent content SHOULD resume. Each page break ends layout in the current page box and causes remaining pieces of the document tree to be laid out in a new page box.
Name: | page-break-before |
Value: | auto | always | avoid | left | right |
Initial: | auto |
Applies to: | block-level elements |
Inherited: | yes |
Percentages: | N/A |
Media: | paged |
Computed value: | specified value |
Name: | page-break-after |
Value: | auto | always | avoid | left | right |
Initial: | auto |
Applies to: | block-level elements |
Inherited: | yes |
Percentages: | N/A |
Media: | paged |
Computed value: | specified value |
Name: | page-break-inside |
Value: | auto | avoid |
Initial: | auto |
Applies to: | block-level elements |
Inherited: | yes |
Percentages: | N/A |
Media: | paged |
Computed value: | specified value |
Values for these properties have the following meanings:
A potential page break location is typically under the influence of the parent element's 'page-break-inside' property, the 'page-break-after' property of the preceding element, and the 'page-break-before' property of the following element. When these properties have values other than 'auto', the values 'always', 'left', and 'right' take precedence over 'avoid'. See the section on allowed page breaks for the exact rules on how these properties MAY force or suppress a page break.
Name: | page |
Value: | auto | <identifier> |
Initial: | auto |
Applies to: | block-level elements |
Inherited: | yes |
Percentages: | N/A |
Media: | paged |
Computed value: | specified value |
The 'page' property can be used to specify a particular type of page where an element SHOULD be displayed.
This example will put all tables on a right-hand side landscape page (named "rotated"):
@page rotated { size: landscape } table { page: rotated; page-break-before: right }
The 'page' property works as follows: If a block box with inline content has a 'page' property that is different from the preceding block box with inline content, then one or two page breaks are inserted between them, and the boxes after the break are rendered on a page box of the named type. See "Forced page breaks" below.
In this example, the two tables are rendered on landscape pages (indeed, on the same page, if they fit), and the page type "narrow" is not used at all, despite having been set on the div:
@page narrow { size: 9cm 18cm } @page rotated { size: landscape } div { page: narrow } table { page: rotated }with this document::
<div> <table>...</table> <table>...</table> </div>
Name: | orphans |
Value: | <integer> |
Initial: | 2 |
Applies to: | block-level elements |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Computed value: | specified value |
Name: | widows |
Value: | <integer> |
Initial: | 2 |
Applies to: | block-level elements |
Inherited: | yes |
Percentages: | N/A |
Media: | visual |
Computed value: | specified value |
The 'orphans' property specifies the minimum number of lines of a paragraph that MUST be left at the bottom of a page. The 'widows' property specifies the minimum number of lines of a paragraph that MUST be left at the top of a page. Examples of how they are used to control page breaks are given below.
In the normal flow, page breaks can occur at the following places:
These breaks are subject to the following rules:
If the above doesn't provide enough break points to keep content from overflowing the page boxes, then rules B and D are dropped in order to find additional breakpoints.
If that still does not lead to sufficient break points, rules A and C are dropped as well, to find still more break points.
A page break MUST occur at (1) if, among the 'page-break-after' and 'page-break-before' properties of all the elements generating boxes that meet at this margin, there is at least one with the value 'always', 'left', or 'right'.
A page break MUST also occur at (1) if the last line box above this margin and the first one below it do not have the same value for 'page'.
CSS3 does not define which of a set of allowed page breaks MUST be used; CSS3 does not forbid a user agent from breaking at every possible break point, or not to break at all. But CSS3 does recommend that user agents observe the following heuristics (while recognizing that they are sometimes contradictory):
Suppose, for example, that the style sheet contains 'orphans : 4', 'widows : 2', and there are 20 lines (line boxes) available at the bottom of the current page:
Now suppose that 'orphans' is '10', 'widows' is '20', and there are 8 lines available at the bottom of the current page:
Counters apply to page contexts defined by means of the '@page' rule. This is useful for maintaining a page count.
The following rules result in the placement of the current page number in the middle of the outside margin of each page.
@page { margin: 10%; counter-increment: page; @top-center { font-family: sans-serif; font-weight: bold; font-size: 2em; content: counter(page); } }
Name: | page-policy |
Value: | start | first | last |
Initial: | start |
Applies to: | counter and string declarations |
Inherited: | N/A |
Percentages: | N/A |
Media: | paged |
Computed value: | specified value |
'page-policy' determines which page-based occurrence of a given element is applied to a counter or string value:
Furthermore, if the counter-reset property is used in the same context, the 'page-policy' MUST be used to determine when a counter or string value is reset.
It is often useful to refer to the total number of pages in a document. A UA MUST act as if there was a counter with the name of 'pages' and its initial value was set to the total number of pages.
The following example produces a centered footer with content like "Page 2 of 5":
@page { counter-increment: page; @bottom-center { content: "Page " counter(page) " of " counter(pages); }
Some CSS profiles might make 'pages' OPTIONAL because it would be too much work for the UAs to compute it. A UA that doesn't support 'pages' SHALL ignore any 'content' property that uses the 'pages' counter. It is therefore possible to write a simple stylesheet that covers UAs with differing capabilities:
The following example produces a centered footer with content like "Page 2 of 5" (if the UA supports 'pages') or something like "Page 2" (if the UA doesn't support 'pages')
@page { counter-increment: page; @bottom-center { content: "Page " counter(page); content: "Page " counter(page) " of " counter(pages); } }
The capability of a float is extended to floating an element to a page float area in a page box. A page float positions an element to page float areas such as the top or bottom float area of the current page box.
Authors specify the dimensions, orientation, margins etc. of a page float area within an @page-float rule. An @page-float rule consists of the keyword '@page-float', white space, one of the following: 'top', 'bottom', 'left', or 'right', optional white space, and then a block of declarations (said to be the page float context).
The following set the bottom page float area to have a top border and to have a maximum height of 50% (relative to the content height of the page box).
@page { @float-area bottom { border-top: solid thin black; max-height: 50% } }
Bottom page floats follow analogous rules.
The following example creates two elements that are floated to the bottom of the page - the second is placed below the first.
*.float { float: bottom } <div class="float">This text should appear near the bottom of the page</div> <div class="float">The second float should appear after the first float</div>
Right page float floats follow analogous rules.
Sometimes it is useful to float an element to a page by itself or to have a page with contains only floating elements. This is done by assigning the float to a named page. An example of this would be a large figure in a document.
The following style sheet rules puts large figures on a page by themselves and not side by side.
.largeFigure { float: left; clear: both page: large-figures } @page large-figures { ... /* definition of the page */ }
...
<div class="largeFigure"> <img src="figure-1.png" alt="Figure-1 - Very large image"/> </div>
Images from camera phones, digital cameras or scanners can appear crooked or sideways. Furthermore, devices such as a camera phone, might not have the capability to correct the image. However, this type of device can accept input from its user on the the kind of correction to perform, such as rotating the image by 90 degrees. The image-orientation property provides a way to specify a rotation to be applied to an image, and, presumably, improve the image's presentation. This facility is not intended to specify other image transformations such as flipping the image in the horizontal or vertical direction. Also, this facility is not needed to correctly orient an image when printing in landscape or portrait orientation.
Name: | image-orientation |
Value: | auto | <angle> |
Initial: | auto |
Applies to: | images |
Inherited: | N/A |
Percentages: | N/A |
Media: | paged |
Computed value: | specified value |
'image-orientation' specifies a rotation in the right or clockwise direction that a user agent should apply to an image.
Two values for the 'image-orientation' property apply to an image:
The following examples rotate the an image in four major orientations: img.original { image-orientation: auto } img.zero { image-orientation: 0grad } img.ninety { image-orientation: 90deg } img.pi { image-orientation: 3.1416rad } img.tilt { image-orientation: -10grad } ... <img class="pi" src=... />