Part Four — Paged Media Chapter Sixteen

Thinking in Pages

The scroll and the page are not the same medium. Working in Paged.js requires a genuine shift in mental model — from continuous flow to discrete, fixed surfaces with their own spatial logic.

Every piece of CSS you have written before this chapter was written for a scroll. Even if the page you were styling happened to fit within a single viewport — even if no scrolling was required — the browser's underlying model was one of infinite vertical space, with content positioned along an axis that could extend without limit. Width was constrained; height was not. The page was a river, not a surface. This model is so deeply embedded in how CSS works that most developers have never had reason to question it. And then they encounter a Paged.js document and discover that an entirely different model applies: one where height is fixed, where overflow means a new page rather than more scroll, where the position of an element on the page matters in a way that has no analog in screen design.

This chapter makes that mental model shift explicit. It describes the CSS Paged Media specification's approach to pages, explains the @page rule and what it controls, introduces the named page system that allows different sections of a document to have different page geometries, and establishes the conceptual vocabulary that all of Part Four will build on. The technical implementations — running headers, page numbers, break controls — come in the chapters that follow. This chapter is about understanding the territory before navigating it.

· · ·

Two models of the page The scroll and the surface

The difference between screen CSS and paged CSS is not primarily technical. It is conceptual. Screen CSS operates on what we might call the scroll model: content is laid out in a continuous vertical flow, and the viewport is a window that moves along that flow. The content exists independently of any particular view; the view is just what happens to be visible at a given scroll position. There is no concept of a "page" in the scroll model — only content, and the viewer's current position within it.

CSS Paged Media operates on the surface model: content is divided into a sequence of discrete, fixed-size surfaces — pages — each with defined dimensions, defined margins, and a defined content area within those margins. When content overflows a page's content area, it does not scroll; it moves to the next page. Each page is a complete composition. The book, report, or document is the sequence of those compositions.

This difference has profound consequences for how you think about layout. In the scroll model, you think about the flow of content through a container of unknown height. In the surface model, you think about the placement of content within a surface of precisely known dimensions. In the scroll model, an element's vertical position is determined by what precedes it in the flow. In the surface model, an element's vertical position is also determined by which page it lands on — a variable that depends on how much content preceded it, how many page breaks occurred, and what page geometry is in effect.

The practical consequence is that you cannot fully predict, at the time of writing the CSS, where any specific element will appear on the page. You can control the conditions under which page breaks occur, and you can control what happens at page boundaries — running headers, page numbers, margin boxes — but the exact position of a paragraph on page 47 depends on all the content that came before it. This is normal, expected, and not a problem. It is simply how paged layout works, and it is how typographers have always worked with flowing text.

The scroll model — screen CSS viewport infinite vertical space — viewport moves
The surface model — paged CSS page 1 — fixed surface page 2 — content overflows → new surface

Figure 16.1 — Two models of the page. Left: the scroll model — content flows through an infinite vertical space; the viewport is a window that moves along it. Content has no inherent concept of pages or surfaces. Right: the surface model — content is divided into fixed-size pages; each page has defined margin zones (shown tinted) and a content area within them. When the content area fills, content moves to the next page. The margin zones — top and bottom here — can carry running headers, page numbers, and other navigational elements generated by the browser independently of the content flow.

· · ·

The @page rule Defining the surface

The @page rule is the CSS declaration that creates a page surface. It defines the physical dimensions of the page, the margins that bound the content area within it, and the margin boxes — the areas within those margins where generated content like running headers and page numbers can appear. Everything that makes a document look like a document, rather than an endless webpage, begins here.

We introduced the basic @page syntax in Chapter 14. Here we go deeper into what the rule controls and how its various components interact. The full structure of a @page rule looks like this:

@page {
  /* 1. Page dimensions                         */
  size: 5.5in 8.5in portrait;

  /* 2. Margin zones (space between edge
        and content area)                        */
  margin-top:     0.75in;
  margin-bottom:  1in;
  margin-inside:  0.625in;
  margin-outside: 0.875in;

  /* 3. Margin boxes — generated content
        placed within the margin zones           */
  @top-center {
    content: string(chapter-title);
    font-family: var(--font-ui);
    font-size:   var(--text-xs);
    color:       var(--ink-faint);
  }

  @bottom-center {
    content: counter(page);
    font-family: var(--font-ui);
    font-size:   var(--text-xs);
    color:       var(--ink-faint);
  }
}

The size property accepts named sizes (A4, letter, A5), explicit dimensions (5.5in 8.5in), and an optional orientation keyword (portrait or landscape). When an orientation keyword is given, the named size is rotated accordingly — size: A4 landscape gives a page that is 297mm wide and 210mm tall.

The margin boxes — the @top-center, @bottom-center, and their siblings — are the mechanism by which Paged.js places content in the page's margin areas. There are sixteen margin box positions in the CSS Paged Media specification, arranged around the four sides of the page. The most commonly used for document design are @top-left, @top-center, @top-right, @bottom-left, @bottom-center, and @bottom-right. We use these in Chapter 17, which covers running headers and page numbers in full detail.

content area (where body text flows) @top-left -corner @top-left @top-center most used @top-right @top-right -corner @bottom-left -corner @bottom-left @bottom-center most used @bottom-right @bottom-right -corner @left-top @left-middle @left-bottom @right-top @right-middle @right-bottom

Figure 16.2 — The sixteen margin box positions. The CSS Paged Media specification defines sixteen named positions within a page's margin area: four corners, three along each of the four sides, giving sixteen in total. The most commonly used in document design are @top-center and @bottom-center — for running headers and page numbers respectively — and @top-left, @top-right, @bottom-left, @bottom-right for asymmetric header and folio designs. Corner boxes and side boxes are available for complex designs but rarely needed for book or report work.

· · ·

Named pages and page sequences Different sections, different surfaces

A real book is not a single page type repeated indefinitely. It has front matter — half-title, title page, copyright, table of contents, preface — that may use different margins, different running headers, and page numbers in a different format (roman numerals, typically) from the main body. It has chapter openers with a dramatic head margin and no running header. It has body pages with consistent margins and a running header and folio. It may have an index or bibliography section with different column structure. Each of these is a different page type — a different named page.

The CSS Paged Media specification handles this through named pages: you define a named @page rule for each page type, and then assign HTML elements to their named page type using the page property. When Paged.js encounters an element with a page property, it places that element on a new page of the named type. The page sequence — the order in which named pages appear — is determined by the order of elements in the HTML source.

/* ── Named page definitions ───────────────────── */

/* Front matter — roman numeral folios,
   no running header                              */
@page front-matter {
  size:            5.5in 8.5in;
  margin-top:      0.75in;
  margin-bottom:   1in;
  margin-inside:   0.625in;
  margin-outside:  0.875in;

  @bottom-center {
    content: counter(page, lower-roman);
    font-size: var(--text-xs);
    color: var(--ink-faint);
  }
}

/* Chapter opener — large drop, no header         */
@page chapter-opener {
  margin-top:      2in;
  margin-bottom:   1in;
  margin-inside:   0.625in;
  margin-outside:  0.875in;
  /* No @top-center — no running header           */
}

/* Body pages — running header + folio            */
@page body {
  margin-top:      0.75in;
  margin-bottom:   1in;
  margin-inside:   0.625in;
  margin-outside:  0.875in;

  @top-left {
    content: string(book-title);
    font-size: var(--text-xs);
    color: var(--ink-faint);
    letter-spacing: 0.08em;
  }

  @top-right {
    content: string(chapter-title);
    font-size: var(--text-xs);
    color: var(--ink-faint);
    letter-spacing: 0.08em;
  }

  @bottom-outside {
    content: counter(page);
    font-size: var(--text-xs);
    color: var(--ink-faint);
  }
}

/* ── Assign elements to named pages ──────────── */
.front-matter     { page: front-matter; }
.chapter-opener   {
  page:         chapter-opener;
  break-before: right; /* always start on recto */
}
.chapter-body     { page: body; }
The Compositor's Garden — page sequence
The Compositor's Garden Half
title
@page blank
The Compositor's Garden Eleanor Voss Title
page
@page blank
Copyright
verso
@page blank
Contents
@page
front-matter
Chapter One Chapter
opener
@page
chapter-opener
Body pages
@page body
··· more
chapters
Notes &
bibliography
@page body

The complete page sequence for The Compositor's Garden. Each distinct page type is assigned to a named @page rule. Front matter pages use a blank page definition with no header or folio. The table of contents and preface use @page front-matter with roman numeral folios. Chapter openers use @page chapter-opener with the large head margin. Body pages use @page body with running headers and outer-edge folios.

· · ·

The mental model shift From scroll to spread

The most important adjustment to make when beginning work with Paged.js is not technical — it is perceptual. Working in a paged medium requires you to think simultaneously at two scales: the page and the spread. The page is the individual surface, with its content, its margins, its running header and folio. The spread is two facing pages considered together — the reader's actual visual experience of a book, where the left and right pages form a single composition.

This dual scale creates considerations that screen design never encounters. A chapter that ends on a recto (right-hand page) leaves a blank verso (left-hand page) before the next chapter begins — unless you design to prevent it. A full-page illustration should, ideally, fall on a recto, where it is seen first as the reader turns the page. A chapter opener should always start on a recto — a convention so ingrained that breaking it feels wrong even in documents where the reader may never consciously notice. These are spread-level decisions, and they require thinking about the sequence of pages rather than any individual page in isolation.

CSS Paged Media provides the break-before: right property to force content to start on a recto page, inserting a blank verso if necessary. The equivalent for a verso start is break-before: left. These properties are essential for managing the page sequence in a double-sided document, and we use them throughout the project for chapter openers.

The other spread-level consideration is the gutter — the two facing inner margins of a spread. As discussed in Chapter 14, the inner margins must be sufficient to account for the binding. But at the spread level, you also need to consider how the two text blocks relate visually. When both pages of a spread have the same top margin, the first lines of text on both pages align horizontally — a continuity that gives the spread a settled, composed feeling. When they don't — because one page has a large pull quote or a chapter drop — the spread feels asymmetric in a way that may or may not be intentional. Being aware of the spread means noticing these relationships.1

Setting up Paged.js

Paged.js is available as a JavaScript file that polyfills the CSS Paged Media specification in any modern browser. For the project document, the simplest setup is to include the Paged.js script in the document's <head> and let it run automatically. The browser preview will show the paginated layout — pages stacked vertically with visible page edges — which you can inspect, adjust, and print to PDF.

Download the latest version of Paged.js from pagedjs.org, or reference the hosted version. Then add the font-loading guard from Chapter 11 to ensure Paged.js does not begin paginating before the fonts have loaded. With that in place, the HTML document you have been building through Parts Two and Three will begin to look like a book.

· · ·

The conceptual groundwork for paged layout is now in place: the surface model, the @page rule, named pages, and the spread-level thinking that connects individual pages into a coherent document sequence. The next three chapters go deep into the specific mechanisms that give a paged document its professional character: running headers and footers in Chapter 17, page numbering and break control in Chapter 18, and the final print-ready output in Chapter 19.