---
title: 'Grid Systems'
source: 'https://academia.sh/en/courses/interface-fundamentals/grid-systems'
course: 'Fundamentals of Interface Design'
language: en
updated: '2026-08-17T18:11:07+00:00'
license: 'CC BY-SA 4.0'
---

# Grid Systems

The arithmetic relationship among container, grid margin, column count, and gutter; deriving column width, computing span widths, and testing the grid against content criteria.

The Visual Principles topic required reducing the number of alignment axes and fitting
values to a scale, but it did not say where those axes and values should come from. As
long as values are chosen one at a time, the inventory swells again: 24 pixels gets
chosen today, 28 pixels on another screen tomorrow, and within two weeks no one can tell
which one is correct.

The **grid** is the structure that turns this choice into a derivation. Once four numbers
are settled, every remaining horizontal measure is computed from those four numbers. This
lesson builds that arithmetic and tests the catalog interface's column division against
content criteria.

## The Grid's Four Variables

A column grid is defined by four numbers:

- **Container width**, the total width of the area the content occupies.
- **Grid margin**, the strip between the container's edge and the first and last column.
  The Visual Presentation with CSS course established `margin` and `padding` as distinct
  properties; the grid margin, however, is a layout decision, and in practice it can be
  built with either property.
- **Column count**, how many equal shares the content area is divided into.
- **Gutter**, the space between two adjacent columns.

The relationship among these four is fixed:

$$
\text{column} = \frac{\text{container} - 2 \cdot \text{grid margin} - (n - 1) \cdot \text{gutter}}{n}
$$

What matters about this relationship is that column width is **not an independent
decision**. Three of the four numbers are chosen, and the fourth is computed. A design
never decides that "the column should be 74 pixels"; 74 comes out as a result.

The width of a block that spans multiple columns is derived the same way. The number of
columns a block covers is called its **span**, and its width includes not only the
columns it covers but the gutters between them: a span of $n$ columns occupies $n$
column widths plus $n-1$ gutters.

## Column Width Is Derived

The program below computes column width for different container widths at fixed grid
margin and gutter values, derives span widths, and compares how divisible different
column counts are.

```js
// 06-grid.mjs — column width arithmetic, span widths, and divisibility

function grid(container, margin, columnCount, gutter) {
  const content = container - 2 * margin;
  const totalGutter = (columnCount - 1) * gutter;
  const column = (content - totalGutter) / columnCount;
  return { content, totalGutter, column };
}

function span(n, column, gutter) {
  return n * column + (n - 1) * gutter;
}

const MARGIN = 24;
const GUTTER = 24;
const COLUMN_COUNT = 12;

console.log("container  content  total gutter  column width  is integer");
for (const k of [1440, 1280, 1200, 1024, 960, 768]) {
  const g = grid(k, MARGIN, COLUMN_COUNT, GUTTER);
  console.log(
    `${String(k).padStart(9)}  ${String(g.content).padStart(7)}  ${String(g.totalGutter).padStart(12)}  ` +
      `${g.column.toFixed(3).padStart(12)}  ${Number.isInteger(g.column) ? "yes" : "NO"}`
  );
}

console.log("");
const base = grid(1200, MARGIN, COLUMN_COUNT, GUTTER);
console.log(`container 1200, margin ${MARGIN}, gutter ${GUTTER}, ${COLUMN_COUNT} columns -> column ${base.column}px`);
console.log("span  width  share of content");
for (const n of [3, 4, 6, 8, 9, 12]) {
  const g = span(n, base.column, GUTTER);
  console.log(
    `${String(n).padStart(4)}  ${String(g).padStart(5)}  ${((100 * g) / base.content).toFixed(1).padStart(15)}%`
  );
}

console.log("");
console.log("column count  divisors (excluding 1 and itself)  equal-share options");
for (const s of [8, 10, 12, 16]) {
  const divisors = [];
  for (let d = 2; d < s; d++) if (s % d === 0) divisors.push(d);
  console.log(`${String(s).padStart(12)}  ${divisors.join(", ").padEnd(34)}  ${divisors.length}`);
}

console.log("");
console.log("content-based check: filter panel >= 240px, results list >= 480px");
for (const container of [1200, 768]) {
  const g = grid(container, MARGIN, COLUMN_COUNT, GUTTER);
  console.log(`  container ${container}px  (column ${g.column}px)`);
  for (const [left, right] of [
    [3, 9],
    [4, 8],
    [5, 7],
  ]) {
    const leftSpan = span(left, g.column, GUTTER);
    const rightSpan = span(right, g.column, GUTTER);
    const status = leftSpan >= 240 && rightSpan >= 480 ? "passes" : "fails";
    console.log(`    ${left}+${right} columns -> ${leftSpan}px + ${rightSpan}px  ${status}`);
  }
}
```

```
container  content  total gutter  column width  is integer
     1440     1392           264        94.000  yes
     1280     1232           264        80.667  NO
     1200     1152           264        74.000  yes
     1024      976           264        59.333  NO
      960      912           264        54.000  yes
      768      720           264        38.000  yes

container 1200, margin 24, gutter 24, 12 columns -> column 74px
span  width  share of content
   3    270             23.4%
   4    368             31.9%
   6    564             49.0%
   8    760             66.0%
   9    858             74.5%
  12   1152            100.0%

column count  divisors (excluding 1 and itself)  equal-share options
           8  2, 4                                2
          10  2, 5                                2
          12  2, 3, 4, 6                          4
          16  2, 4, 8                             3

content-based check: filter panel >= 240px, results list >= 480px
  container 1200px  (column 74px)
    3+9 columns -> 270px + 858px  passes
    4+8 columns -> 368px + 760px  passes
    5+7 columns -> 466px + 662px  passes
  container 768px  (column 38px)
    3+9 columns -> 162px + 534px  fails
    4+8 columns -> 224px + 472px  fails
    5+7 columns -> 286px + 410px  fails
```

In the first table, the rows that stand out are the 1280 and 1024 containers: column
width does not come out as an integer, giving 80.667 and 59.333. This means the grid's
alignment axes do not land on exact pixel positions.

The conclusion to draw from this is not that the grid is broken. The conclusion is this:
**a grid is not a pixel specification, it is a division rule.** When column width comes
out fractional, the design decision attaches not to a measured value like "74 pixels" but
to a ratio like "a four-column span." A design tied to a measured value has to be
re-measured at every container width; a design tied to a ratio adapts on its own.
Whether a fractional width leaves a visible seam depends on the browser's layout phase,
and the design should not depend on it.

The second table gives span widths. In the catalog interface, the filter panel occupies
270 pixels with a 3-column span, and the results list occupies 858 pixels with a
9-column span. The total, 270 + 24 + 858 = 1152, is exactly the content width. The 24
pixels between them is a gutter; no additional space is added between the two blocks.
The most common mistake when using a grid is adding a margin on top of the gutter; the
result produces an axis that is not part of the grid.

## Why Twelve Columns

The third table shows why column count is not arbitrary. A grid's job is to be able to
divide content into equal shares; what has value, then, is not the column count itself
but how many distinct equal divisions that count permits.

Twelve columns divide by 2, 3, 4, and 6: halves, thirds, quarters, and sixths can all be
built. Eight columns divide only by 2 and 4; a three-way division is not possible.
Sixteen columns divide by 2, 4, and 8, which again does not give a three-way division,
but it does provide finer adjustment.

This does not mean twelve is a rule. The criterion is this: **column count is the
smallest number that satisfies the divisions the content requires.** If the catalog
interface requires both two-way and three-way divisions, twelve is enough; if it requires
only two-way division, eight produces fewer decisions, and fewer decisions mean less
inconsistency.

## Testing the Grid Against Content

A grid is not correct or incorrect on its own; it is evaluated once tested against
content. The catalog interface has two criteria: the filter panel needs at least 240
pixels so filter labels fit without wrapping; the results list needs at least 480 pixels
so record titles keep a readable line length.

The fourth table applies this criterion to three divisions. At a 1200-pixel container,
all three divisions pass; the choice among them is made on other grounds. The 3+9
division is preferred in the catalog because it gives the results list the most room: the
screen's primary task is scanning results, and the filter is a secondary tool.

At a 768-pixel container, though, **no division passes.** The 5+7 division gives the
filter 286 pixels, but only 410 pixels are left for the results list; the 4+8 division
fails both criteria. This is not a failure of the grid — it is information the grid
provides: a two-column layout cannot be built at this width. Insisting on keeping the two
blocks side by side makes both of them unusable.

The same calculation also says where the layout change should happen. The smallest
container width at which the results list can hold 480 pixels is found at the point
where an 8-column span equals 480; below that, the layout switches to a single column.
How this transition is defined is the subject of the Responsive and Adaptive Layout
lesson.

## Grid Types

A column grid is not the only type; other grids are chosen depending on content
structure.

- **Manuscript grid** consists of a single text block and the margins around it. The
  description text in the record detail view uses this grid; it does not need division.
- **Column grid** is the structure computed above: horizontal division, vertical freedom.
- **Modular grid** adds one more division to the column grid, this time horizontal; rows
  are also split into equal heights. Results lists presented as cards use this grid,
  because a card's width and height both need to align.
- **Baseline grid** ties the vertical measure to the text's line height; every line of
  text sits on a shared horizontal line. Its cost is high: the line height of every text
  level, at every size, has to conform to a shared divisor.

The selection criterion is which axis the content needs to align on. If only horizontal
alignment is needed, a column grid is enough; if vertical alignment is needed too, the
cost of a modular or baseline grid is worth accepting.

## Summary

- A grid is defined by four numbers: container width, grid margin, column count, and
  gutter. Column width is not an independent decision; it is a result derived from these
  four.
- A span's width is the sum of the columns it covers and the gutters between them; no
  additional space is added between blocks placed on the grid — the gutter already does
  that job.
- Column width does not come out as an integer at every container; the design attaches
  to the span ratio, not to a measured pixel value.
- The value of a column count is how many equal divisions it permits; twelve is common
  because it divides by 2, 3, 4, and 6, but the criterion is the smallest number that
  satisfies the divisions the content requires.
- A grid is tested against the content's minimum width requirements; a width at which no
  division satisfies the criteria marks the point where the layout needs to change.
- Grid type is chosen based on which axis the content needs to align on; if vertical
  alignment is not needed, the cost of modular and baseline grids is not paid.

## Next Step

The grid made the horizontal measure derivable: column boundaries are no longer chosen,
they are computed. The vertical measure, though, is still free — the gutter was chosen
as 24 pixels, the grid margin was chosen as 24 pixels, but where these numbers came from
was never said. The inventory pulled out in the Repetition and Consistency lesson swelled
in exactly this gap. The next lesson ties spacing values to a production rule: it
computes and compares linear, geometric, and hybrid scales, and measures how many steps
a scale needs to cover the catalog interface's 13 raw spacing values.
