Part Three — Grid and Layout Chapter Thirteen

Building a Grid in CSS

CSS Grid gives you the most precise spatial control available in any document medium. Learning to use it deliberately — not just conveniently — is the difference between a layout that holds and one that drifts.

There is a moment when you write display: grid for the first time and realise that the browser is doing something fundamentally different from what CSS has ever done before. You are not positioning elements relative to each other, or floating them into columns, or using flexbox to arrange them in a single axis. You are defining a spatial system first — a grid of columns and rows — and then placing elements into it. The layout exists before the content. The structure precedes the material. This is how print designers have always worked, and CSS Grid is the first CSS layout system that reflects that sequence correctly.

This chapter translates the grid decisions made in Chapter 12 into working CSS. We build the project grid from first principles, explaining each property as we introduce it. We then develop grid templates for the three most common document structures — single column with margin column, symmetric two-column, and asymmetric text-plus-notes — so that the code becomes a reusable toolkit rather than a one-off solution.

· · ·

CSS Grid fundamentals Tracks, cells, and the explicit grid

CSS Grid introduces a vocabulary that is worth knowing precisely, because it makes the documentation and the error messages legible. A grid container is any element with display: grid. Its direct children become grid items. The container defines tracks — columns and rows — using grid-template-columns and grid-template-rows. The intersection of a column track and a row track is a cell. A grid item can occupy one cell or span multiple cells using grid-column and grid-row.

The explicit grid is what you define with grid-template-columns and grid-template-rows. If grid items are placed beyond its boundaries, CSS Grid creates an implicit grid to contain them, using default track sizes unless you specify otherwise with grid-auto-rows or grid-auto-columns. For document layout, you almost always want to work in the explicit grid — defining all the tracks you need in advance rather than relying on implicit creation.

The unit that makes CSS Grid uniquely powerful for layout is fr — the fractional unit. One fr represents one fraction of the available space in the grid container after fixed-size tracks and gaps are subtracted. grid-template-columns: 1fr 2fr creates two columns, the second twice as wide as the first, filling the full container width. grid-template-columns: 200px 1fr creates a fixed 200px column and a flexible column that takes whatever remains. This is the unit you use for content tracks whose width should adapt to the container while maintaining their proportional relationship to each other.1

Gaps between tracks are specified with gap, column-gap, and row-gap. Unlike margins, gaps do not collapse and do not appear at the outer edges of the grid — only between tracks. For a document with two text columns and a gutter between them, column-gap is the correct tool. For vertical spacing between major block elements in a grid layout, row-gap can supplement or replace margin-based spacing.

Item A col 1 / row 1 Item B — spanning columns 2–3 grid-column: 2 / 4 Item C col 1 / row 2 Item D col 2 / row 2 Item E col 3 / row 2 column track gap 1 2 3 4 5 6 row 1 row 2

Figure 13.1 — CSS Grid anatomy. A three-column grid with two row tracks. Column line numbers (1–6) appear above; the gap regions are shown in a lighter tint between column tracks. Item B spans columns 2 through 4 using grid-column: 2 / 4, demonstrating how elements can occupy multiple tracks. Item C occupies a single cell. The gap appears between items but not at the outer edges of the grid container.

· · ·

The project grid Building the Compositor's Garden layout in CSS

The grid for The Compositor's Garden, decided in Chapter 12, is a single text column with a narrower margin column on the outer edge — the side furthest from the spine. The inner margin is narrower, the outer wider, and the margin column sits within the outer margin space for marginal notes. In CSS Grid, this is expressed as a three-track column definition: a fixed inner margin, a flexible text column, and a fixed outer margin column.

We define the grid on the page body — the content area inside the Paged.js page box — and use named grid areas to make placement readable. Named areas are more maintainable than numeric line references, especially as the document grows more complex:

/* ── Page body grid — The Compositor's Garden ── */
.page-body {
  display:               grid;

  /* Three columns:
     - inner margin (fixed, narrow)
     - text column  (flexible, fills space)
     - outer margin (fixed, wider — for notes) */
  grid-template-columns: 2rem 1fr 6rem;

  /* Named areas for readable placement       */
  grid-template-areas:
    "margin  text  notes";

  /* Gutter between text and notes column      */
  column-gap:            1.5rem;
}

/* ── Place elements in named areas ─────────── */
.chapter-title,
.chapter-intro,
p, h2, h3,
blockquote, figure,
.footnotes {
  grid-area: text;
}

/* Full-width elements span all three columns  */
.full-width {
  grid-column: 1 / -1;
}

/* Marginal notes sit in the notes column      */
.marginal-note {
  grid-area:   notes;
  font-size:   var(--text-xs);
  font-style:  italic;
  color:       var(--ink-faint);
  line-height: 1.5;
  padding-top: 0.2rem;
}
The Compositor's Garden — page grid grid-template-columns: 2rem 1fr 6rem
inner text column (1fr) notes On Spacing The space between letters grid-area: text chapter title grid-area: notes marginal note grid-area: text footnotes grid-column: 1 / -1 running header

Figure 13.2 — The Compositor's Garden page grid. Three column tracks: a narrow inner margin (2rem), the main text column (1fr), and a notes column (6rem) in the outer margin. The running header spans all three columns with grid-column: 1 / -1. All body elements — headings, body text, subheadings, footnotes — are placed in the text column. Marginal notes are placed in the notes column, positioned to align with the relevant passage in the main text.

· · ·

Aligning to a baseline grid Making vertical rhythm visible in CSS

A baseline grid is an invisible horizontal grid — a series of evenly spaced lines at the interval of the body text's line-height — against which every element on the page is positioned. When elements align to the baseline grid, the vertical rhythm is consistent: the eye follows a regular beat from line to line, from element to element, across the full page. When elements do not align, the rhythm is broken: the page has a slightly turbulent quality that readers feel as discomfort even when they cannot name it.

Achieving strict baseline grid alignment in CSS is technically possible but requires care. The key insight is that every element's top edge and bottom edge must fall on a grid line. Since grid lines are spaced at the body line-height interval, this means every vertical distance — every margin, padding, and element height — must be a multiple of the line-height unit.

For the project, the body line-height is 1.76 applied to a 1.175rem font size, giving a line-height in absolute terms of approximately 2.07rem. We define this as a custom property and derive all vertical spacing from it:

/* ── Baseline grid unit ─────────────────────── */
:root {
  /* Body: 1.175rem × 1.76 ≈ 2.07rem per line   */
  --lh: 2.07rem; /* one baseline unit            */
}

/* ── Heading: margin must land on grid ────────
   h2 is font-size 1.65rem × line-height 1.25
   = 2.0625rem per line ≈ one baseline unit
   Use margin-top: calc(3 × var(--lh))
   and margin-bottom: calc(1 × var(--lh))       */
h2 {
  font-size:     var(--text-lg);   /* 1.65rem */
  line-height:   1.25;
  margin-top:    calc(3 * var(--lh));
  margin-bottom: calc(1 * var(--lh));
}

/* ── Figure: total height must be grid multiple */
figure {
  margin-top:    calc(2 * var(--lh));
  margin-bottom: calc(2 * var(--lh));
}

In practice, strict baseline alignment breaks down whenever an element has an unpredictable height — an image at an arbitrary size, a block quotation that wraps to an odd number of lines, a code block. The pragmatic approach is to apply baseline-grid mathematics to headings, section breaks, and major structural elements, and to accept that flowing text may drift slightly from strict alignment without visible consequence.2

WITHOUT BASELINE GRID WITH BASELINE GRID Chapter heading Section heading Chapter heading Section heading

Figure 13.3 — Baseline grid alignment. Left: heading and subheading margins set arbitrarily — text baselines drift from the grid lines (shown as faint horizontal rules), producing inconsistent vertical rhythm. The red circles mark misaligned baselines. Right: margins calculated as multiples of the baseline unit — every text baseline lands on a grid line, producing even vertical rhythm across the full column. The green circles confirm alignment.

· · ·

Grid templates for common document types Reusable layouts beyond the project

The single-column-with-notes grid built above is specific to The Compositor's Garden. Part Five of this book covers different document types — reports, academic papers, editorial layouts — each of which may need a different grid. The following are ready-to-use CSS Grid templates for three common structures.

Template A: Symmetric two-column — appropriate for academic journals, reference documents, and technical manuals where parallel text streams are needed or where a wide page format makes a single column impractical:

/* ── Two-column symmetric grid ──────────────── */
.page-body-2col {
  display:               grid;
  /* Outer margins + two equal columns + gutter */
  grid-template-columns: 2rem 1fr 1fr 2rem;
  grid-template-areas:
    "margin-l  col-a  col-b  margin-r";
  column-gap:            2rem;
}

/* Full-width elements: headings, rules, notes */
.full-width   { grid-column: 1 / -1; }
.col-a        { grid-area:   col-a; }
.col-b        { grid-area:   col-b; }

Template B: Asymmetric text-plus-sidebar — appropriate for reports and documentation where a narrow sidebar carries navigation, labels, or supplementary data alongside the main text:

/* ── Asymmetric: main text + sidebar ────────── */
.page-body-sidebar {
  display:               grid;
  /* Sidebar (fixed) + gutter + main text (flex) */
  grid-template-columns: 10rem 2rem 1fr;
  grid-template-areas:
    "sidebar  .  main";
}

.sidebar      { grid-area: sidebar; }
.main-content { grid-area: main; }

Template C: Full-bleed with centred measure — appropriate for long-form articles and essays on wide screens or large-format pages where the text block should be centred with very wide margins:

/* ── Full-bleed with centred text measure ────── */
.page-body-centred {
  display:               grid;
  /* Flexible outer margins keep text centred    */
  grid-template-columns: 1fr minmax(0, 38rem) 1fr;
  grid-template-areas:
    ".  content  .";
}

.content      { grid-area: content; }
TEMPLATE A — SYMMETRIC 2-COL TEMPLATE B — SIDEBAR TEMPLATE C — CENTRED

Figure 13.4 — Three reusable grid templates. Left: symmetric two-column — equal columns with a gutter, full-width headings spanning both. Centre: asymmetric sidebar — a fixed-width sidebar for navigation or labels beside a flexible main text column. Right: centred measure — flexible outer margins keep the text column centred at a fixed maximum width, appropriate for wide pages or large-format documents. Each template is built from the same CSS Grid properties; only the column track definitions differ.

Project checkpoint

The CSS grid for The Compositor's Garden is now defined. The three-column template — inner margin, text column, notes column — is in the project stylesheet, grid areas are named, and element placement is specified. The spacing system from Chapter 9 provides the vertical rhythm, and the baseline grid mathematics are applied to headings and major structural elements.

At this point, the project document has its typography (Part Two) and its spatial structure (the grid from this chapter). What it lacks is the specific spatial values that turn the grid into a page: the margins from the edge of the physical page to the grid container, the page dimensions themselves, and the CSS Paged Media declarations that tell Paged.js how to paginate the document. That is the work of Chapter 14.

· · ·

CSS Grid and document layout are a natural pair — the grid's explicit, named structure matches the way print designers have always thought about pages. The translation from design intention to CSS is direct, the code is readable, and the result is a spatial system that can be applied consistently across an entire document without drift or approximation.

Chapter 14 moves outward from the content grid to the page itself — the @page rule, margin boxes, and the physical dimensions that turn a styled HTML document into a paginated book.