Read CSS: The Definitive Guide, 3rd Edition Online
Authors: Eric A. Meyer
Tags: #COMPUTERS / Web / Page Design
In a paged medium,
it's a good idea to exert some influence over how page breaks
are
placed. You can affect page breaking using the propertiespage-break-before
andpage-break-after
, both of which accept the same set of
values.
page-break-before, page-break-after
auto
|always
|avoid
|left
|right
|inherit
auto
Nonfloated block-level elements with aposition
value ofrelative
orstatic
No
As specified
The default value ofauto
simply
means that a page break is not forced to come before or after an element. This is
the same as any normal printout.always
causes
a page break to be placed before (or after) the styled element.
For
example, assume you have a situation where the page title is anh1
element, and the section titles are allh2
elements. You might want a page break right before
the beginning of each section of a document and after the document title. This
would result in the following rules, illustrated in
Figure
14-4
:
h1 {page-break-after: always;}
h2 {page-break-before: always;}
Figure 14-4. Inserting page breaks
If you want the document title to be centered in its page, of course,
you would add rules to that effect. Since you don't, you just get a very
straightforward rendering of each page.
The valuesleft
andright
operate in the same manner asalways
, except
they further define the type of page on which printing can resume. Consider the
following:
h2 {page-break-before: left;}
This
will force everyh2
element to be preceded by
enough page breaks so that theh2
will be
printed at the top of a left page—that is, a page surface that would appear to the
left of a spine if the output were bound. In double-sided printing, this would
mean printing on the "back" of a piece of paper.
So let's assume that,
in printing, the element just before anh2
is
printed on a right page. The previous rule would cause a single page break to be
inserted before theh2
, thus pushing it to the
next page. If the nexth2
is preceded by an
element on a left page, however, theh2
would
be preceded by two page breaks, thus placing it at the top of the next left page.
The right page between the two would be intentionally left blank. The valueright
has the same basic effect, except it
forces an element to be printed at the top of a right page, preceded by either one
or two page breaks.
The companion toalways
isavoid
, which directs the
user agent to do its best to avoid placing a page break either before or after an
element. To extend the previous example, suppose you have subsections whose titles
areh3
elements. You want to keep these titles
together with the text that follows them, so you want to avoid a page break
following anh3
whenever
possible:
h3 {page-break-after: avoid;}
Note,
though, that the value is calledavoid
, notnever
. There is no way to absolutely
guarantee that a page break will never be inserted before or after a given
element. Consider the
following:
img {height: 9.5in; width: 8in; page-break-before: avoid;}
h4 {page-break-after: avoid;}
h4 + img {height: 10.5in;}
Now,
suppose further that you have a situation where anh4
is placed between two images, and its height calculates to half an
inch. Each image will have to be printed on a separate page, but there are only
two places theh4
can go: at the bottom of the
page holding the first element, or on the page after it. If it's placed after the
first image, then it must be followed by a page break, since there's no room for
the second image to follow it, as shown in
Figure 14-5
.
Figure 14-5. Necessary page breaking
On the other hand, if theh4
is
placed on a new page following the first image, there won't be room on that same
page for the second image. So, again, there will be a page break after theh4
. And, in either case, at least one image,
if not both, will be preceded by a page break. There's only so much the user agent
can do, given a situation like this one.
Obviously, situations such as
these are rare, but they can happen—for example, in a case where a document
contains nothing but tables preceded by headings. There may be cases where tables
print in such a way that they force a heading element to be followed by a page
break, even though the author requested that such break placement be
avoided.
The same sorts of issues can arise with the other page-break
property,page-break-inside
. Its possible
values are more limited than those of its cousins.
page-break-inside
auto
|avoid
|inherit
auto
Nonfloated block-level elements with aposition
value ofrelative
orstatic
Yes
As specified
Withpage-break-inside
, you pretty
much have one option other than the default: you can request that a user agent try
toavoid
placing page breaks within an element.
If you have a series of "aside" divisions, and you don't want them broken across
two pages, you could
declare:
div.aside {page-break-inside: avoid;}
Again,
this is a suggestion more than an actual rule. If an aside turns out to be longer
than a page, obviously the user agent can't help but place a page break inside the
element.
In an effort to provide finer influence over page
breaking, CSS2 defines two properties common to both traditional print typography
and desktop publishing:widows
andorphans
.
widows, orphans
inherit
2
Block-level elements
Yes
As specified
These properties have similar aims but approach them from different
angles. The value ofwidows
defines the minimum
number of line boxes found in an element that can be placed at the top of a page
without forcing a page break to come before the element.orphans
has the same effect in reverse: it gives the minimum number
of line boxes that can appear at the bottom of a page without forcing a page break
before the element.
Let's takewidows
as an example. Suppose you
declare:
p {widows: 4;}
This
means that any paragraph can have no fewer than four line boxes appear at the top
of a page. If the layout of the document would lead to fewer line boxes, then the
entire paragraph is placed at the top of the page. Consider the situation shown in
Figure 14-6
. Cover up the top part
of the figure with your hand, so only the second page is visible. Notice that
there are two line boxes there, from the end of a paragraph that started on the
previous page. Given the defaultwidows
value
of2
, this is an acceptable rendering. However,
if the value were3
or higher, the entire
paragraph would appear at the top of the second page as a single block. This would
require that a page break be inserted before the paragraph in
question.
Figure 14-6. Counting the widows
Look again at
Figure 14-6
,
but this time cover up the second page with your hand. Notice the four line boxes
at the bottom of the page, at the beginning of the last paragraph. This is fine as
long as the value oforphans
is4
or less. If it were5
or higher, the paragraph would again be preceded by a page break and
be laid out as a single block at the top of the second page.
Of
course, bothorphans
andwidows
must be satisfied. If an author declared the
following, most paragraphs would be without an interior page
break:
p {widows: 30; orphans: 30;}
It
would take a pretty lengthy paragraph to allow an interior page break given those
values. Of course, if the intent is to prevent interior breaking, it would be
better expressed
as:
p {page-break-inside: avoid;}
Because CSS2 allows for some odd page-breaking
styles, it defines a set of behaviors regarding allowed page breaks and "best"
page breaks. These behaviors guide user agents in how they should handle page
breaking in various circumstances.
There are really only two generic
places where page breaks are permitted. The first of these is between two
block-level boxes. If a page break falls between two block boxes, then themargin-bottom
value of the element before
the page break is reset to0
, as is themargin-top
of the element following the page
break. However, there are two rules that allow a page break to fall between two
element boxes:
If the value ofpage-break-after
for
the first element—or the value ofpage-break-before
for the second element—isalways
,left
, orright
. This is true
regardless of the value for theother element, even if it'savoid
. (This is a
forced
page break.)
If the value of the first element'spage-break-after
value isauto
, and the same is true for the second element'spage-break-before
value, and if they do not
share an ancestor element whosepage-break-inside
value is notavoid
.
Figure 14-7
illustrates all of the
possible page-break placements between elements in a hypothetical document. Forced
page breaks are represented as a filled square, whereas potential (unforced) page
breaks are shown as an open square.
Figure 14-7. Potential page-break placement between block boxes
The second generic place where page breaks are allowed is between two
line boxes
inside a block-level box. This, too, is governed by a pair of
rules:
A page break may appear between two line boxes only if the number of line
boxes between the start of the element and the line box before the page
break would be less than the value oforphans
for the element. Similarly, a page break can be placed
only where the number of line boxes between the line box after the page
break and the end of the element is less than the value ofwidows
.
A page break can be placed between line boxes if the value ofpage-break-inside
for the element is notavoid
.
In both cases, the second of the two rules controlling
page-break placement is ignored if no page-break placement can satisfy all the
rules. Thus, given a situation where an element has been givenpage-break-inside
:avoid
but is longer than a full page, a page break is permitted inside
the element, between two line boxes. In other words, the second rule regarding
page-break placement between line boxes is ignored.
If ignoring the
second rule in each pair of rules still does not yield good page-break placement,
other rules can also be ignored. In such a situation, the user agent is likely to
ignore all page-break property values and proceed as if they were allauto
, although this approach is not defined (or
required) by the CSS specification.
In addition to the previously
explored rules, CSS2 defines a set of "best" page-breaking
behaviors:
Break as few times as possible.
Make all pages that don't end with a forced break appear to have about
the same height.
Avoid breaking inside a block that has a border.
Avoid breaking inside a table.
Avoid breaking inside a floated element.
These recommendations aren't required of user agents, but they
offer logical guidance that should promote ideal page-breaking behaviors.