Shortname: css-page Level: 3 Status: ED Group: csswg ED: http://dev.w3.org/csswg/css-page/ TR: http://www.w3.org/TR/css3-page/ Previous Version: http://www.w3.org/TR/2013/WD-css3-page-20130314/ !Issue Tracking: http://www.w3.org/Style/CSS/Tracker/products/13 Editor: Elika J. Etemad, Invited Expert, formerly Mozilla, http://fantasai.inkedblade.net/contact Editor: Simon Sapin, Mozilla, formerly Kozea, http://exyr.org/about/ Ignored terms: fit, fit-position Link defaults: css-break (property) break-after, css21 (property) display, css21 (property) min-height, css21 (property) max-height, css21 (property) min-width, css21 (property) max-width, css21 (property) margin, css-content-3 (property) counter-increment, css-content-3 (property) counter-reset Abstract: This CSS module specifies how pages are generated and laid out to hold fragmented content in a paged presentation. It adds functionality for controlling page margins, page size and orientation, and headers and footers, and extends generated content to enable page numbering and running headers / footers. The process of paginating a flow into such generated pages is covered in [[!CSS3-BREAK]].
Paged media (e.g., paper, transparencies, photo album pages, pages displayed on computer screens as printed output simulations) differ from continuous media in that the content of the document is split into one or more discrete static display surfaces. To handle pages, CSS3 Paged Media describes how:
This module 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.
Although CSS3 does not specify how user agents transfer page boxes to sheets, it does include certain mechanisms for telling user agents about the intended page sheet size and orientation. In the general case, CSS3 assumes that one page box will be transferred to one surface of similar size.
All properties defined in this specification also accept the inherit keyword as their value, but for readability it has not been listed explicitly.
The following terminology and accompanying diagrams help to describe the page model:
In the paged media formatting model, the document is transferred into one
or more page boxes. The page box is a specialized CSS
box that maps to a rectangular print media surface, such as a page of paper.
It is roughly analogous to the viewport.
As with other CSS boxes, a page box consists of margin, border, padding, and content areas. The content and margin areas of a page box have special functions:
In CSS 2.1, both the page box and page area are simple rectangles. Neither is a CSS box with margins, borders, and padding. This CSS box should be distinct from the page box and page area, which would be its margin area and content area, respectively. Naming ideas?
The properties of a page box are determined by properties
declared within the
page context, which is the
declaration block of the
@page
rule. Similarly the properties of a page-margin box
are determined by properties declared within its margin context.
Declarations in the page context can affect the page box and/or inherit
to the page-margin boxes, but they do not apply to or inherit into the
document's root element or other content.
The containing block of the page box is specified using the 'size' property in the page context. The width and horizontal margins of the page box are then calculated exactly as for a non-replaced block element in normal flow. [[!CSS21]] The height and vertical margins of the page box are calculated analogously (instead of using the block height formulas). In both cases if the values are over-constrained, instead of ignoring any margins, the containing block is resized to coincide with the margin edges of the page box.
When drawing a page of content, the page layers are painted in the following painting order (bottommost first):
In the page model, the page background behaves similar to the root background: its background painting area is the bleed area, which covers the entire page box, including its margins (regardless of 'background-clip'). Page backgrounds are anchored within the page box's padding area by default (and honor 'background-origin' if the UA supports [[!CSS3BG]]). However if 'background-attachment' is ''fixed'' then the image is positioned relative to the page box including its margins (i.e. the background positioning area is the page's margin box).
The document canvas background is drawn as the page box's background: by default its background painting area covers the page box's border box, and for UAs that support [[!CSS3BG]], follows the 'background-clip' value specified on the root element. It remains, however, positioned with respect to the root element or page area as usual.
With respect to the page-margin boxes,
the document canvas, page borders, and all of the document contents
are treated as a single element with a z-index
value of '0'
that establishes a
stacking context
[[!CSS21]]:
the page-margin boxes never interleave with parts of the document content
or between the content and the canvas.
They may only paint in front of the document content
or behind the document canvas.
The page background is always painted underneath everything else.
The 'z-index' property applies to page-margin boxes. Since the 'position' property does not apply to page-margin boxes, 'z-index' always affects page-margin boxes as if they were positioned elements regardless of the 'position' property's value. Each page-margin boxes always establishes a stacking context.
The default painting order, or CSS2.1 Appendix E "tree order", of page-margin boxes with respect to each other is as follows:
Start with ''@top-left-corner'', then go clockwise. This order is arbitrary but can be overridden with 'z-index'. It only has a visible effect when page-margin boxes overlap, which should not happen in most cases.
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'' can generate a box that is wider than the page box. As another example, when boxes are positioned absolutely or relatively, they may end up in "inconvenient" locations. For example, images may be placed on the edge of the page box or 100,000 meters below the page box.
A specification for the exact formatting of such elements lies outside the scope of this document. However, it is recommended that authors and user agents observe the following general principles concerning content outside the page box:
Content should be allowed slightly beyond the page box to allow pages to "bleed".
User agents SHOULD avoid generating a large number of content-empty pages to honor the positioning of elements (e.g., printing 100 blank pages is probably neither the author's nor the user's intent). A Content-empty page is a page box whose page area contains no printable content other than backgrounds and/or borders. A page box whose page area contains generated content, or content whose visibility is ''hidden'', or invisible content such as a zero-width space is not a content-empty page. On the other hand, a page containing only a background and/or borders and/or page-margin box content is a content-empty page.
Note, however, that generating a small number of empty page boxes is sometimes necessary to honor the forced-break values for 'page-break-before'/'break-before' and 'page-break-after'/'break-after'. [[!CSS21]] [[!CSS3-BREAK]]
Authors SHOULD NOT position elements in inconvenient locations just to avoid rendering them. Instead:
This specification does not define how boxes positioned outside the page box are handled. Possibilities include discarding them or creating page boxes for them at the end of the document.
CSS distinguishes between left pages and right pages on all documents,
whether they are printed duplex or not. Each left page is followed by a
right page and vice versa. Left and right pages can be styled differently
with the :left
and :right
pseudo-classes.
Whether the first page of a document is a left page or a right page depends on the page progression of the document. The page progression is the direction in which the printed pages of a document would be sequenced when laid out side-to-side. For example, English and horizontally-set Japanese typically progress from left to right, whereas Arabic and vertically-set Japanese pages typically progress from right to left. In documents with a left-to-right page progression the first page of the document is a right page, and vice versa.
The page progression direction is determined as follows:
If the UA supports the 'direction' and 'writing-mode' properties from the CSS 3 Writing Modes Module [[CSS3-WRITING-MODES]], it must determine whether the first page is a left or right page from the values of those properties on the root element.
To explicitly force a document to begin printing on a left or right page,
authors can specify a 'break-before' value
that that propagates a page break to the root. [[!CSS3-BREAK]]
The UA must suppress the first (empty) page(s) in this case
(and the :first
pseudo-class matches the first printed page).
html { break-before: always }
For an HTML document with a left-to-right page progression, the above style rule will cause the first page of the document to print on a ':left' page
html { break-before: left }
For an HTML document, the above style rule will cause the first page of the document to print on a ':left' page, regardless of the page progression.
Authors can specify various aspects of a page box, such as its dimensions, orientation, and margins, within an ''@page'' rule. ''@page'' rules are allowed wherever rule-sets are allowed. An ''@page'' rule consists of the keyword ''@page'', an OPTIONAL comma-separated list of page selectors and a block of declarations (said to be in the page context). An ''@page'' rule can also contain other at-rules, interleaved between declarations. The current level of this specification only allows margin at-rules inside ''@page''.
''@page'' rules without a selector list apply to every page. Other ''@page'' rules apply to pages that match at least one of their selectors. Properties declared within the page context apply to the page box.
If an error is encountered during the processing of a declaration block within a page or a margin context, the Rules for handling parsing errors apply; that is, valid declarations within the block are applied.
A page selector is made of either a page type selector or a page pseudo-class, followed by zero or more additional page pseudo-classes. No whitespace is allowed between components of a selector. The page selector grammar and examples can be found below.
A page selector is said to match a given page if and only if all of its components match the page.
A page type selector is a case-sensitive CSS identifier [[!CSS21]]. It matches pages of the named page type generated by the 'page' property. A page type name of ''auto'' (ASCII case-insensitive) does not make the rule invalid, but MUST never match.
A page pseudo-class is ASCII case-insensitive and has the same syntax as pseudo-classes in regular Selectors. [[!SELECT]] The various page pseudo-classes are defined below.
When printing double-sided documents, left and right pages are often formatted differently. This can be expressed by using the '':left'' and '':right'' page pseudo-classes.
All pages are automatically classified by user agents as either left pages or right pages, based on page progression. The :left and :right pseudo-classes only match left or right pages, respectively.
@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 (i.e., a printer that only prints on one side of the medium must nevertheless produce correctly formatted output).
Note. Adding declarations to the '':left'' or '':right'' pseudo-class does not necessarily influence whether the document comes out of the printer double- or single-sided (which is outside the scope of this specification).
The :first pseudo-class matches the first printed page of a document.
@page { margin: 2cm } /* All margins set to 2cm */ @page :first { margin-top: 10cm /* Top margin on first page 10cm */ }
The :blank pseudo-class matches content-empty pages that appear as a result of forced page breaks.
Only the ''left'', ''right'', ''recto'' and ''verso'' values of the 'break-before' and 'break-after' properties can generate pages that match '':blank''.
In this example, forced page break may occur before h1
elements.
h1 { break-before: left } @page :blank { @top-center { content: "This page is intentionally left blank" } }
A page matched by '':blank'' can also be matched by other page pseudo-classes.
If headers have been specified on all right pages, a blank right
page will be matched by both :blank
and :right
. Therefore, margin boxes set on right pages
will have to be removed unless they are wanted on blank pages. Here is
an example where the top center header is removed from blank pages,
while the page number remains:
h1 { break-before: left } @page :blank { @top-center { content: none } } @page :right { @top-center { content: "Preliminary edition" } @bottom-center { content: counter(page) } }
Due to the higher specificity of :blank
over :right
, the top center header is removed even
if content: none
comes before content: "Preliminary
edition"
.
Note. Future versions of CSS may include other page pseudo-classes.
The syntax for the @page rule is a specialization of the generic at-rule defined by CSS 2.1. This grammar extends the at-rule syntax to allow @page rules nested inside @media rules. User agents MUST adhere to the following grammar:
See [[!CSS21]], Section 4.1.1 and Appendix G for the expansion of missing productions:
All new lexical tokens are specializations of the ATKEYWORD lexical token:
PAGE_SYM ::= "@page" TOPLEFTCORNER_SYM ::= "@top-left-corner" TOPLEFT_SYM ::= "@top-left" TOPCENTER_SYM ::= "@top-center" TOPRIGHT_SYM ::= "@top-right" TOPRIGHTCORNER_SYM ::= "@top-right-corner" 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" LEFTBOTTOM_SYM ::= "@left-bottom" RIGHTTOP_SYM ::= "@right-top" RIGHTMIDDLE_SYM ::= "@right-middle" RIGHTBOTTOM_SYM ::= "@right-bottom" media : MEDIA_SYM S* medium [ COMMA S* medium ]* LBRACE S* [ page_rule | ruleset ]* '}' S* ; page_rule : PAGE_SYM S* page_selector_list '{' S* page_body '}' S* ; page_selector_list : [ page_selector S* [ ',' page_selector S* ]* ]? ; page_selector : pseudo_page+ | IDENT pseudo_page* ; pseudo_page : ':' [ "left" | "right" | "first" | "blank" ] ; page_body : /* Can be empty */ declaration? [ ';' S* page_body ]? | page_margin_box page_body ; page_margin_box : margin_sym S* '{' S* declaration? [ ';' S* declaration? ]* '}' S* ; margin_sym : TOPLEFTCORNER_SYM | TOPLEFT_SYM | TOPCENTER_SYM | TOPRIGHT_SYM | TOPRIGHTCORNER_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 are examples of page selectors (declaration block intentionally left blank)
@page { ... } @page :left { ... } @page :right { ... } @page LandscapeTable { ... } @page CompanyLetterHead:first { ... } /* identifier and pseudo page. */ @page:first { ... } @page toc, index { ... } @page :blank:first { ... }
The following are examples of page-margin boxes where the declaration blocks are intentionally left blank.
@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 page and margin contexts cascade just like declarations in style rule for elements.
The specificity of page a selector is computed in a manner analogous to the computations defined in the Selectors module:
Given the syntax of page seletors, f can only ever be 0 or 1.
Note: Repeated occurrences of the same pseudo-classes are allowed and do increase specificity.
Due to storage limitations, implementations may have limitations on the size of f, g, or h. If so, values higher than the limit must be clamped to that limit, and not overflow.
Specificities are compared by comparing the three components in order (f, g, h): the specificity with a larger f value is more specific; if the two f values are tied, then the two g values are compared, etc. If all the values are tied, the two specificities are equal.
Some page specificity calculation examples follow:
@page { } /* specificity = (0,0,0) */ @page :left { } /* specificity = (0,0,1) */ @page :first { } /* specificity = (0,1,0) */ @page :blank:left { } /* specificity = (0,1,1) */ @page artsy { } /* specificity = (1,0,0) */ @page artsy:left { } /* specificity = (1,0,1) */ @page artsy:first { } /* specificity = (1,1,0) */
Consider the following usage example:
@page :left { margin-left: 4cm; } @page { margin-left: 3cm; }
Due to the higher specificity of the pseudo-class selector, the left margin on left pages will be 4cm and all other pages (the right-facing pages) will have a left margin of 3cm.
In this example, the higher specificity of the green rules wins over the red rule. Therefore the first page will have blue text in the top-left page-margin box and green text in the top-right page-margin box, while subsequent pages will have red text in the page-margin boxes.
@page :first { color: green; @top-left { content: "foo"; color: blue; } @top-right { content: "bar"; } } @page { color: red; @top-center { content: "Page " counter(page); } }
Page contexts cascade, so the following stylesheet would style pages with 25 millimeter margins and 14 point type in the page-margin boxes:
@page { margin: 25mm;} @page { font-size: 14pt;}
Page-margin boxes are boxes within the page margin that, like pseudo-elements, can contain generated content.
Page-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.
Typically, a page header is located at the top of the page in documents with a predominately horizontal writing direction and on the side opposite the binding edge for documents with a predominately vertical writing direction. One possible design of page headers for horizontally written documents uses the ''@top-left-corner'', ''@top-left'', ''@top-center'', ''@top-right'' and ''@top-right-corner'' page-margin boxes. Another design, for vertically written documents, could use the ''@right-top'', ''@right-middle'', and ''@right-bottom'' page-margin boxes for right facing pages and ''@left-top'', ''@left-middle'', and ''@left-bottom'' for left facing pages.
The page footer is typically at the opposite end of the page from the page header. For example, the design of a horizontally written document with a page header at the top of the page could use the ''@bottom-left-corner'', ''@bottom-left'', ''@bottom-center'', ''@bottom-right'' and ''@bottom-right-corner'' page-margin boxes as the page footer. The design of a vertically written document could use the page-margin boxes of the binding edge of the page for the page footer.
Page-margin boxes are positioned with respect to the page area and are independent of page orientation, for example the top page-margin boxes are above the page area in both portrait and landscape orientation. The various page-margin boxes are defined and illustrated in the diagram below:
Box | Description | Placement |
---|---|---|
top-left-corner | a fixed-size box defined by the intersection of the top and left margins of the page box | ![]() |
top-left | a variable-width box filling the top page margin between the top-left-corner and top-center page-margin boxes | ![]() |
top-center | a variable-width box centered horizontally between the page's left and right border edges and filling the page top margin between the top-left and top-right page-margin boxes | ![]() |
top-right | a variable-width box filling the top page margin between the top-center and top-right-corner page-margin boxes | ![]() |
top-right-corner | a fixed-size box defined by the intersection of the top and right margins of the page box | ![]() |
left-top | a variable-height box filling the left page margin between the top-left-corner and left-middle page-margin boxes | ![]() |
left-middle | a variable-height box centered vertically between the page's top and bottom border edges and filling the left page margin between the left-top and left-bottom page-margin boxes | |
left-bottom | a variable-height box filling the left page margin between the left-middle and bottom-left-corner page-margin boxes | |
right-top | a variable-height box filling the right page margin between the top-right-corner and right-middle page-margin boxes | ![]() |
right-middle | a variable-height box centered vertically between the page's top and bottom border edges and filling the right page margin between the right-top and right-bottom page-margin boxes | |
right-bottom | a variable-height box filling the right page margin between the right-middle and bottom-right-corner page-margin boxes | |
bottom-left-corner | a fixed-size box defined by the intersection of the bottom and left margins of the page box | ![]() |
bottom-left | a variable-width box filling the bottom page margin between the bottom-left-corner and bottom-center page-margin boxes | ![]() |
bottom-center | a variable-width box centered horizontally between the page's left and right border edges and filling the bottom page margin between the bottom-left and bottom-right page-margin boxes | ![]() |
bottom-right | a variable-width box filling the bottom page margin between the bottom-center and bottom-right-corner page-margin boxes | ![]() |
bottom-right-corner | a fixed-size box defined by the intersection of the bottom and right margins of the page box | ![]() |
Page-margin boxes are created by margin at-rules inside the page context. Authors should put these rules after any declarations in the page context as legacy clients may not handle declarations after margin at-rules correctly.
A margin at-rule consists of an ATKEYWORD that identifies the page-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(page); } }
As with the '':before'' and '':after'' pseudo-elements, a specified 'content: normal' on a page-margin box computes to ''none''. A page-margin box is generated if and only if the computed value of its 'content' property is not ''none''. Otherwise, no box is generated, as for elements with ''display: none''.
The 'display' property does not apply to page-margin boxes.
The following style sheet creates a green box in each corner of the page except the bottom-left corner.
@page { @top-left-corner { content: " "; border: solid green; } @top-right-corner { content: url(foo.png); border: solid green; } @bottom-right-corner { content: counter(page); border: solid green; } @bottom-left-corner { content: normal; border: solid green; } }
The width and height of each page-margin box is determined by the rules below. These rules define the equivalent of CSS2.1 Sections 10.3 and 10.6 for page-margin boxes.
The rules for applying 'min-height', 'max-height', 'min-width', and 'max-width' [[!CSS21]] do apply to page-margin boxes and may imply a recalculation of the width, height, and/or margins if the dimensions resulting from the specified 'width' or 'height' violate their constraints. If the UA does not support the 'min-height' or 'min-width' properties then it must behave as if 'min-height' and 'min-width' were always zero.
In addition to the box model definitions in CSS2.1 [[!CSS21]], and the sizing terms in CSS Intrinsic Sizing [[!CSS3-SIZING]], the following terms are defined for use in the subsequent page-margin box calculations:
The containing block for a page-margin box depends on its location:
For a corner page-margin box, it is the rectangle defined by the intersection of the two page margins meeting at that corner.
For all other page-margin boxes, the containing block is the rectangle formed by the encapsulating page margin minus the containing blocks of the adjacent corners' page-margin boxes. This means that the size of this containing block is given in one dimension by the used page margin and in the other dimension by the available width (for top and bottom page-margin boxes) or available height (for left and right page-margin boxes).
The following rules apply to ''@top-left'', ''@top-center'' and ''@top-right'' page-margin boxes, which are referred to as A, B, and C, respectively, in this section.
If the 'margin-left' or 'margin-right' property of any of the three boxes computes to ''auto'', the used value is zero.
The following algorithm determines the used width of each box. For this purpose, boxes that are not generated are assumed to have a 'width' and an outer width of zero.
Note: The high-level goals are (in order of priority) to center the middle box (B) if it is generated, to minimize overflow and overlap, and to distribute space proportionally to the amount of content.
If the middle box (B) is not generated, distribute the available width to A and C as follows:
max-content width + flex space × flex factor ÷ ∑flex factors
min-content width + flex space × flex factor ÷ ∑flex factors
If the middle box (B) is generated, determine the ''auto'' widths of A, B, and C as follows:
(available width − used outer widths of B) ÷ 2
The 'min-width' and 'max-width' properties [[CSS21]] apply to page-margin boxes in the variable dimension like on normal elements, except that the three boxes on the same side are considered together.
More precisely:
Once the dimensions of the boxes are determined, they are positioned as follows:
The used values for ''@bottom-left'', ''@bottom-center'' and ''@bottom-right'' page-margin boxes are established by the same rules as for ''@top-left'', ''@top-center'', and ''@top-right'', respectively.
The used values for ''@left-top'', ''@left-middle'' and ''@left-bottom'' boxes are established by the same rules, with "width" replaced by "height", "left" by "top", "right" by "bottom" and "center" by "middle".
The used values for ''@right-top'', ''@right-middle'' and ''@right-bottom'' page-margin boxes are established by the same rules as for ''@left-top'', ''@left-middle'' and ''@left-bottom'', respectively.
The rules below are used to calculate the used values of each ''@top-left-corner'', ''@top-left'', ''@top-center'', ''@top-right'', and ''@top-right-corner'' page-margin box's 'height', 'margin-top', and 'margin-bottom' properties:
'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' = top page margin
The same rules apply to the bottom page-margin boxes (bottom-left-corner, bottom-left, bottom-center, bottom-right, and bottom-right-corner), except that in the overconstrained case, the 'margin-bottom' is ignored rather than the 'margin-top'.
Analogous rules govern the properties for the left and right page-margin boxes with respect to 'width' (top-left-corner, left-top, left-middle, left-bottom, and bottom-left-corner; top-right-corner, right-top, right-middle, right-bottom, bottom-right-corner), with "top" replaced by "left", "bottom" replaced by "right", and "height" replaced by "width". In the overconstrained case for left (right) page-margin boxes, the specified value of 'margin-left' ('margin-right') is ignored.
The following is a collection of examples of page-margin box usage.
Here is an example of a page with only a top-left header:
@page { @top-left { content: "Header in Left Cell (top-left)" } }
Because there are no contents defined for the top-center or the top-right page-margin boxes, the extent of the top-left page-margin box is allowed to cross the center of the page box.
The following is an example of a page with a centered header:
@page { @top-center { content: "Header in Center Cell (top-center)" } }
The following is an example of a page with a single header in the top-right page-margin box:
@page { @top-right { content: "Header in Right Cell (top-right)" } }
Because the content of the center cell is empty, the extent of the top-right page-margin box is allowed to cross the center of the page box.
The following is an example of a page with a top-center and a top-left header:
@page { @top-left { content: "Left Cell (top-left)" } @top-center { content: "Header in Center Cell (top-center)" } }
The following is an example of a page with a top-center and a top-right header:
@page { @top-center { content: "Header in Center Cell (top-center)" } @top-right { content: "Right Cell (top-right)" } }
The following is an example of a page with top-left and top-right headers:
@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 are no center cell contents, the extent of the top-left is allowed to cross the center of the page box.
Appendix A defines the normative list of CSS 2.1 [[!CSS21]] properties that apply to page boxes. If a conforming user agent supports any of these properties on block boxes, then it MUST also support that property in the page context. This specification additionally defines the 'size' property that only applies in the page context.
Properties that apply to the page-margin boxes can also be set within the page context: if inheritable or explicitly inherited (with the ''inherit'' keyword in the margin context), they will inherit to the page-margin boxes.
The same appendix defines the normative list of CSS 2.1 [[!CSS21]] properties that apply to page-margin boxes. If a conforming user agent supports any of these properties on block boxes, then it MUST also support that property in the margin context.
Other properties defined by [[!CSS21]] do not apply in these contexts. Behavior for properties not included in CSS 2.1 is undefined.
Note: The intent of leaving other properties undefined is to allow the gradual addition of appropriate CSS3 properties as they emerge, without having to update this specification with each addition.
As with elements in the document, both the page context and the margin context have a computed value for every property, even if that property does not apply to the page or page-margin box.
The normal rules for CSS properties apply with the following exceptions:
It is recommended that user agents establish a default page margin via the user agent stylesheet that includes any non-printable area. It is further recommended that authors assume that the default page area will not include unprintable regions.
Counters can be defined and controlled within an ''@page'' rule, and used as content in page-margin boxes. This is useful for maintaining a page count.
A 'counter-increment' within either a page or margin context causes the counter to increment with the generation of each page box.
If a counter is reset or incremented within the page context, it is in scope for all page-margin boxes and obscures all counters of the same name within the document.
If a counter is reset or incremented within a margin context, it is in scope for that page-margin box and obscures any counters of the same name in both the page context and the document.
If a counter that has not been reset or incremented within the margin context or the page context is used by counter() or counters() in the margin context, then the resultant value is exactly as if the page-margin box were an element within the document at the start of the page, inside the deepest element in the normal flow that spans the page break. Use of the counter in this way does not affect the calculation of the counter's value.
A counter named ''page'' is automatically created and incremented by 1 on every page of the document, unless the 'counter-increment' property in the page context explicitly specifies a different increment for the ''page'' counter. The implied ''page'' counter is a real counter, and can be directly affected using the 'counter-increment' and 'counter-reset' properties when named explicitly in those properties. It can also be used in the 'counter()' and 'counters()' function forms.
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%; @top-center { font-family: sans-serif; font-weight: bold; font-size: 2em; content: counter(page); } }
Adding the following rule will make all pages even-numbered.
@page { counter-increment: page 2; }
Additionally, a counter named ''pages'' is automatically created by the UA. Its value is always the total number of pages in the document. (In continuous media this is always 1.) The value of ''pages'' cannot be manipulated: while 'counter-reset' and 'counter-increment' statements that set it are valid, they have no effect.
In all other respects, page-associated counters behave as described in [[!CSS21]], Nested Counters and Scope and Counters.
Properties used within page or margin contexts take their initial values from their respective property definitions; however, user agents must behave as though the values in the following table were established by rules in the UA default style sheet.
Page-margin box | 'text-align' | 'vertical-align' |
---|---|---|
top-left-corner | right | middle |
top-left | left | middle |
top-center | center | middle |
top-right | right | middle |
top-right-corner | left | middle |
left-top | center | top |
left-middle | center | middle |
left-bottom | center | bottom |
right-top | center | top |
right-middle | center | middle |
right-bottom | center | bottom |
bottom-left-corner | right | middle |
bottom-left | left | middle |
bottom-center | center | middle |
bottom-right | right | middle |
bottom-right-corner | left | middle |
This example style sheet could be used to create a centered header with the current chapter name:
body {counter-reset: chapter;} div.chapter {counter-increment: chapter;} @page { margin: 10%; @top-center { content: "Chapter" counter(chapter) } }
People around the world use many 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. One way to achieve this goal is to utilize the 'size' property, which indicates that the document should preferentially be displayed on a surface of a certain size; another method is to use Media Queries [[MEDIAQ]] which allow different style sheets to be applied to different page sizes.
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 target size and orientation of the page box’s containing block. In the general case, where one page box is rendered onto one page sheet, the 'size' property also indicates the size of the destination page sheet.
The size of a page box can either be "absolute" (fixed size) or "scalable" (i.e., fitting available sheet sizes). The first three values in the table below can be used to create scalable page boxes. Other values define a fixed-size page box, and thereby indicate the preferred output media size. When possible, output should be rendered on the media size indicated. If the specified size is not available, the rules for transposing a page box to a different size apply.
If a size
property declaration is qualified by a ''width'',
''height'', ''device-width'', ''device-height'', ''aspect-ratio'',
''device-aspect-ratio'' or ''orientation''
media query [[!MEDIAQ]] (or other conditional on the size of the paper), then
the declaration must be
ignored. Media
queries do not honor 'size': they assume the paper size that would be chosen
if no @page rules were specified.
It would be useful if media queries could respond at least to sizes specified on an unqualified @page.
Another option could be to do like ''@viewport'' rules [[CSS-DEVICE-ADAPT]]: First apply ''@page'' rules (matching which selectors?), using the UA’s default page size for Media Queries and viewport-percentage lengths [[CSS3VAL]]. The resulting page size is the "base page size". The entire set of stylesheets is applied again, this time using the "base page size" for Media Queries and viewport-percentage lengths.
In the following example
@page { size: 4in 6in; } @media (max-width: 6in) { @page { size: letter; } }
The second size
declaration is ignored, i.e. the specified value
of the size
property is 4in 6in
.
Value | Description |
---|---|
auto | The page box will be set to a size and orientation chosen by the UA. In the usual case, the page box size and orientation is chosen to match the target media sheet. |
landscape | Specifies that the page's content be printed in landscape orientation. The
longer sides of the page box are horizontal. If a < |
portrait | Specifies that the page's content be printed in portrait orientation. The
shorter sides of the page box are horizontal. If a < |
<length> | The page box will be set to the given absolute dimension(s). If only one length value is specified, it sets both the width and height of the page box (i.e., the box is a square). If two length values are specified, the first establishes the page box width, and the second the page box height. Values in units of ''em'' and ''ex'' refer to the page context's font. Negative lengths are illegal. |
< |
A page size can be specified using one of the following media names. This is
the equivalent of specifying 'size'
using length values. The definition of the the media names comes from
Media Standardized Names [[!PWGMSN]].
|
The <
@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 should be rendered on a page sheet size of 210 mm by 297 mm.
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 21mm and 29.7mm. Assuming there are no page borders or padding set in the UA default style sheet, the resulting page area is 189mm by 367.3mm (210mm-21mm by 297mm-29.7mm).
@page { size: auto;/* auto is the initial value */ margin: 10%; }
@page { size: 8.5in 11in;/* width height */ }
The above example sets the width of the page box to be 8.5 inches and the height to be 11 inches. This indicates that the page sheet size should be 8.5"x11" and the orientation ''portrait''.
This section is informative.
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.
Name: marks Value: none | [ crop || cross ] Initial: none Applies To: page context Inherited: no Computed Value: as specified Media: paged
This property adds crop and/or registration marks to the document. These are printed outside the page box to facilitate the trimming and alignment of sheets of paper. Values have the following meanings:
Note that crop marks and registration marks are only visible if the page box is smaller than the printable area.
To set crop and cross marks on a document, this code can be used:
@page { marks: crop cross }
Name: bleed Value: auto | <> Initial: auto Applies To: page context Inherited: no Percentages: N/A Computed Value: as specified Media: paged
This property specifies the extent of the bleed area outside the page box; in other words the extent beyond the page box at which the page rendering is clipped. Values have the following meanings:
If a page box does not match the target page sheet dimensions, the user agent should do one of the following (in order of preference):
The user agent MAY wish to consult the user before performing these operations.
When the page box is smaller than the page sheet, the user agent SHOULD either:
The user agent MAY wish to consult the user in this regard.
The CSS Fragmentation Module [[!CSS3-BREAK]] module defines how and where CSS boxes can be fragmented, including across page breaks. It defines a few properties that indicate where the user agent MAY or MUST break pages, and on what page (left or right) the subsequent content resumes. 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 |
---|---|
Value: | auto | <identifier> |
Initial: | auto |
Applies to: | boxes that create class A break points |
Inherited: | no (but see prose) |
Percentages: | N/A |
Media: | paged |
Computed value: | specified value |
The 'page' property is used to specify a particular type of page (called a named page) on which an element MUST be displayed. If necessary, a forced page break is introduced and a new page generated of the specified type.
This page can be styled by using the same type name in a page selector.
Page type names are case-sensitive identifiers. However the ''auto'' value, being a CSS keyword, is ASCII case-insensitive.
The 'page' property does not inherit. However, if the 'page' value on an element is ''auto'', then its used value is the value specified on its nearest ancestor with a non-auto value. When specified on the root element, the used value for ''auto'' is the empty string.
Because a previous version of this specification indicated that the 'page' property is inherited, an implementation that inherits the 'page' property and treats ''auto'' as always naming the empty string remains conformant to CSS Paged Media Level 3. Note that this exception will be removed in Level 4. Therefore authors should not explicitly specify the ''auto'' value on a descendant of an element with a non-''auto'' value, as the resulting behavior will be unpredictable.
The 'page' property works as follows:
Note: A first or last child box is not always generated by a first or last child element. For example, an element could only have a previous sibling with 'display: none' which does not generate any box.
Essentially, the two 'page' values compared are those from the deepest boxes meeting at the class A break point, ignoring any subtrees rooted by boxes to which the 'page' property does not apply.
See [[!CSS3-BREAK]] for additional details on page breaks.
In this example, the two tables are rendered on landscape pages (indeed, on the same page, if they fit). The page type "narrow" is used for the <p> after the second table, as the page properties for the table element are no longer in effect:
@page narrow { size: 9cm 18cm } @page rotated { size: landscape } div { page: narrow } table { page: rotated }with this document:
<div> <table>...</table> <table>...</table> <p>This text is rendered on a 'narrow' page</p> </div>
In Japanese documents, sometimes different parts of a single document will have different kihon hanmen. [[JLREQ]] The 'page' property, together with ''@page'' rules specifying different page widths, can accomodate this type of layout:
<!DOCTYPE html> <html lang="ja"> <style> html { writing-mode: vertical-rl; line-height: 1.6; } .main { page: main; columns: 2; column-gap: 1rem; } .index { page: index; columns: 3; column-gap: 1rem; } @page { margin: auto; /* center kihon hanmen on page */ width: 40rem; } /* 1.6 × 25 lines */ @page main { height: 61rem; } /* 2 × 30 chars + 1 × gap */ @page index { height: 62rem; } /* 3 × 20 chars + 2 × gap */ </style> <section class="main"> ... </section> <section class="index"> ... </section> </html>
This section has been moved to [[CSS3-IMAGES]].
This list is described in the Page Properties section.
bidi properties | direction |
background properties | background-color |
background-image | |
background-repeat | |
background-attachment | |
background-position | |
background | |
border properties | border-top-width |
border-right-width | |
border-bottom-width | |
border-left-width | |
border-width | |
border-top-color | |
border-right-color | |
border-bottom-color | |
border-left-color | |
border-color | |
border-top-style | |
border-right-style | |
border-bottom-style | |
border-left-style | |
border-short-style | |
border-top | |
border-right | |
border-bottom | |
border-left | |
border | |
counter properties | counter-reset |
counter-increment | |
color | |
font properties | font-family |
font-size | |
font-style | |
font-variant | |
font-weight | |
font | |
height properties | height |
min-height | |
max-height | |
line-height | |
margin properties | margin-top |
margin-right | |
margin-bottom | |
margin-left | |
margin | |
outline properties | outline-width |
outline-style | |
outline-color | |
outline | |
padding properties | padding-top |
padding-right | |
padding-bottom | |
padding-left | |
padding | |
quotes | |
text properties | letter-spacing |
text-align | |
text-decoration | |
text-indent | |
text-transform | |
white-space | |
word-spacing | |
visibility | |
width properties | width |
min-width | |
max-width |
This list is described in the Page Properties section.
bidi properties | direction |
unicode-bidi | |
background properties | background-color |
background-image | |
background-repeat | |
background-attachment | |
background-position | |
background | |
border properties | border-top-width |
border-right-width | |
border-bottom-width | |
border-left-width | |
border-width | |
border-top-color | |
border-right-color | |
border-bottom-color | |
border-left-color | |
border-color | |
border-top-style | |
border-right-style | |
border-bottom-style | |
border-left-style | |
border-short-style | |
border-top | |
border-right | |
border-bottom | |
border-left | |
border | |
counter properties | counter-reset |
counter-increment | |
content | |
color | |
font properties | font-family |
font-size | |
font-style | |
font-variant | |
font-weight | |
font | |
height properties | height |
min-height | |
max-height | |
line-height | |
margin properties | margin-top |
margin-right | |
margin-bottom | |
margin-left | |
margin | |
outline properties | outline-width |
outline-style | |
outline-color | |
outline | |
overflow | |
padding properties | padding-top |
padding-right | |
padding-bottom | |
padding-left | |
padding | |
quotes | |
text properties | letter-spacing |
text-align | |
text-decoration | |
text-indent | |
text-transform | |
white-space | |
word-spacing | |
vertical-align | |
visibility | |
width properties | width |
min-width | |
max-width | |
z-index |
Often, but not always, the page box has a one-to-one correspondence to the physical surface onto which the document is ultimately rendered. The CSS3 page model specifies formatting within the page box, but it is the user agent's responsibility to transfer the page box to the sheet. Some user agent transfer possibilities that are not addressed by CSS3 include:
Changes since the 14 March 2013 Working Draft are:
The CSS Working Group would like to give very special thanks to this module's former editors: Robert Stevahn (Hewlett-Packard), Håkon Wium Lie (Opera Software), Jim Bigelow (Hewlett-Packard), Jacob Refstrup (Hewlett-Packard), and Melinda Grant (Hewlett-Packard).
We would also like to acknowledge our expert contributors Michael Day (YesLogic), Shinyu Murakami (Antenna House), Peter Linss (Hewlett-Packard), and the other members of the CSS Working Group and www-style community who have provided review and comment on CSS Paged Media Level 3.