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

# Density Decisions

Deriving information density from the task; computing records per screen, scan cost, and spacing ratio from row height.

The spacing scale said which values spacing could take, not which step gets used where.
This question takes its most concrete form in the catalog results list: should a record
row's padding be 6 pixels or 16 pixels?

The question looks aesthetic, but its consequence is arithmetic. Padding determines row
height, row height determines how many records appear on a screen, and that determines
how many screens are needed to scan 200 results. This lesson computes that chain from end
to end.

## Density Is Derived from the Task

**Information density** is the amount of meaningful information per unit of screen area.
High density shows more information at once; low density gives each piece of information
more room.

Neither is generally better. The correct density is derived from the screen's primary
task, and two task types pull in opposite directions:

- **Scanning task.** The user is searching for one item among many. The decision
  criterion is a single field — most often the title. In this task, every additional
  pixel of space raises the odds that the item being searched for falls off the screen.
- **Evaluation task.** The user is choosing by comparing among a small number of items.
  The decision criterion is multiple fields: author, year, edition, shelf availability.
  In this task, crowding causes the fields to blur into each other.

The catalog interface has both tasks, but not on the same screen. The results list is a
scanning screen; the record detail view is an evaluation screen. Applying the same
density decision to both breaks both of them.

## Computing the Chain

The program below computes a record row's total height for three density levels, and
derives from it the number of records per screen, the number of fields shown on screen,
the number of screens needed to scan 200 results, and the number of screens to page
through to reach the record ranked 137th. The `row` column in the output is the record
row's total height; the `text` column is the portion of that height taken up by lines of
text.

```js
// 08-density.mjs — records per screen and scan cost from row height

const VIEWPORT_HEIGHT = 900;
const FIXED_AREA = 260; // header, search field, and filter strip
const LIST_AREA = VIEWPORT_HEIGHT - FIXED_AREA;

const RESULT_COUNT = 200;
const TARGET_RANK = 137; // the searched record's rank in the list

const TOUCH_THRESHOLD = 24; // WCAG 2.5.8 minimum target size (CSS px)

const levels = [
  { name: "compact", fontSize: 14, multiplier: 1.4, padding: 6, fieldCount: 1 },
  { name: "balanced", fontSize: 16, multiplier: 1.5, padding: 12, fieldCount: 2 },
  { name: "spacious", fontSize: 16, multiplier: 1.6, padding: 16, fieldCount: 3 },
];

console.log(`list area: ${LIST_AREA}px   result count: ${RESULT_COUNT}   target rank: ${TARGET_RANK}`);
console.log("");
console.log("level    row  text  space  records/screen  fields/screen  screens  to target  touch");
for (const d of levels) {
  const lineHeight = Math.round(d.fontSize * d.multiplier);
  const text = d.fieldCount * lineHeight;
  const row = text + 2 * d.padding + 1; // 1px divider line
  const spaceRatio = (100 * (row - text)) / row;
  const recordsPerScreen = Math.floor(LIST_AREA / row);
  const fieldsOnScreen = recordsPerScreen * d.fieldCount;
  const screenCount = Math.ceil(RESULT_COUNT / recordsPerScreen);
  const screensToTarget = Math.ceil(TARGET_RANK / recordsPerScreen);
  const touch = row >= TOUCH_THRESHOLD ? "passes" : "fails";

  console.log(
    `${d.name.padEnd(8)} ${String(row).padStart(4)}px ${String(text).padStart(6)} ` +
      `${spaceRatio.toFixed(1).padStart(6)}% ${String(recordsPerScreen).padStart(12)} ` +
      `${String(fieldsOnScreen).padStart(11)} ${String(screenCount).padStart(6)} ` +
      `${String(screensToTarget).padStart(7)} ${touch.padStart(8)}`
  );
}

// The compact level's padding is 6px; it is not in the hybrid spacing scale (4, 8, 12, 16, 24, ...).
// For the two neighboring steps that land on the scale, the same chain is recomputed.
console.log("");
console.log("fitting the compact level to the scale (font 14, multiplier 1.4, single field)");
console.log("padding  row  records/screen  screens for 200 results  to target");
for (const p of [4, 6, 8]) {
  const row = Math.round(14 * 1.4) + 2 * p + 1;
  const records = Math.floor(LIST_AREA / row);
  console.log(
    `${String(p).padStart(7)}px ${String(row).padStart(6)}px ${String(records).padStart(12)} ` +
      `${String(Math.ceil(RESULT_COUNT / records)).padStart(21)} ${String(Math.ceil(TARGET_RANK / records)).padStart(13)}`
  );
}
```

```
list area: 640px   result count: 200   target rank: 137

level    row  text  space  records/screen  fields/screen  screens  to target  touch
compact    33px     20   39.4%           19          19     11       8   passes
balanced   73px     48   34.2%            8          16     25      18   passes
spacious  111px     78   29.7%            5          15     40      28   passes

fitting the compact level to the scale (font 14, multiplier 1.4, single field)
padding  row  records/screen  screens for 200 results  to target
      4px     29px           22                    10             7
      6px     33px           19                    11             8
      8px     37px           17                    12             9
```

## What Changes Is Not the Amount of Information, but Its Shape

The most instructive column in the output is `fields/screen`: 19, 16, 15. Across the
three density levels, the total number of fields visible on screen is nearly the same,
with only a 21 percent difference.

This breaks the common framing of the density debate. The claim "a compact layout shows
more information" is not true; a compact layout shows **more records**, a spacious layout
shows **more fields per record**. The total information a screen carries is roughly
constant. The decision is not about the amount of information but its distribution: the
titles of 19 records, or three fields each for 5 records?

With this framing, the task distinction turns directly into a rule. In the scanning task,
the user needs many titles; the compact layout shows 19 records, and record 137 is
reached in 8 screens. The spacious layout takes 28 screens to reach the same record —
three and a half times as many. In the evaluation task, by contrast, the spacious layout
gives all three fields of every record at once, and the user does not have to enter the
detail view to compare.

## Spacing Ratio Misleads Intuition

The output's `space` column says the opposite of what is expected: the compact row's
space ratio is 39.4 percent, the spacious row's is 29.7 percent. The layout named
"spacious" allocates a **smaller** portion of its row height to space.

The contradiction is only apparent. In the spacious layout, the row is long because it
contains three lines of text; even though padding rises to 16 pixels, the text's share
grows faster. The ratio falls while absolute space rises: the compact row has 13 pixels
of space in total, the spacious row has 33.

Two conclusions follow. First, the words "spacious" and "compact" do not by themselves
give a measure; which quantity is being measured has to be stated. Second, there are two
distinct ways to change density, and their effects differ: **changing padding** affects
row height linearly, while **changing the field count** jumps row height by a full line
height. In the spacious layout, padding is 2.67 times the compact layout's, but row
height rises to 3.36 times; the source of the difference is the two extra fields.

A designer who wants to lower density first has to know which lever they are pressing.
Adding a field is expensive and hard to reverse; changing padding is cheap and moves
between scale steps.

## Where Density Draws from the Scale

The calculation itself reveals an inconsistency. The compact level's padding is 6 pixels,
and this value is not on the hybrid spacing scale chosen in the previous lesson — 4, 8,
12, 16, 24, and onward. The density decision has stepped outside the scale.

The output's second block shows what fitting to the scale changes. If padding is pulled
down to 4 pixels, the row drops to 29 pixels, 22 records appear on screen, and record 137
is reached in 7 screens. If raised to 8 pixels, the row goes to 37 pixels, records per
screen to 17, and reaching the target to 9 screens. The off-scale 6 pixels sits between
these two and gains nothing: the 4-pixel step shows more records, the 8-pixel step
separates them more comfortably, and 6 pixels carries the rationale of neither.

This clarifies the relationship between the scale and density. The scale **discretizes**
the density decision: instead of infinitely many intermediate values, it leaves a
countable handful of options. The consequence of each option — records per screen, scan
cost — can be computed in advance. Density thereby stops being a dial and becomes a
choice; a choice can be justified, an intermediate value cannot.

## Leaving Density to the User

There are cases where the task distinction cannot be resolved on a single screen: the
same results list might be used for both quick scanning and comparison. In that case,
density is turned into a setting, and the user chooses.

This solution's cost is real and often underestimated. Every density level is a separate
layout: separate row height, separate field set, separate overflow behavior. Two levels
mean twice the testing. The choice also needs to persist — if the user has to choose
again every session, the setting is a burden rather than a convenience.

The criterion is this: **a density setting is added only when both tasks can be shown to
be primary.** If one of the two tasks is clearly dominant, no setting is added; the
correct density is chosen for the dominant task, and the other task is moved to a
separate screen. In the catalog interface, the results list exists for scanning and the
record detail view for evaluation; no setting is needed.

## The Lower Bound of Density

Density cannot be raised without limit. The output's last column shows whether the record
row meets the 24 CSS pixels required by the WCAG 2.5.8 criterion: all three levels pass.

But 2.5.5, the enhanced form of the same criterion, raises the target size to 44 CSS
pixels. The compact layout's 33-pixel row falls below this threshold; the balanced
layout's 73 pixels and the spacious layout's 111 pixels are above it. So if the entire
row is a clickable target, the compact layout meets only the lowest threshold.

This shows that the density decision cannot be made independently of input type. The
same 33-pixel row is comfortable in a pointer-driven environment and a missed target in a
touch-driven one. The exact measure of this dependency is computed in the topic's last
lesson.

## Summary

- Information density is not a preference; it is a decision derived from the screen's
  primary task. The scanning task pulls toward higher density, the evaluation task
  toward lower.
- Record row height determines records per screen, which determines scan cost: record
  137 is reached in 8 screens at the compact level, 28 at the spacious level. The total
  number of fields visible on screen, by contrast, stays roughly constant (19, 16, 15);
  what changes is not the amount of information but its distribution across records.
- Spacing ratio misleads intuition: the spacious layout's space ratio is lower, because
  what grows row height is not padding but the added lines of text.
- The density decision draws from the spacing scale's steps; when 4 or 8 is chosen
  instead of the off-scale 6-pixel padding, records per screen become 22 or 17, and both
  choices can be justified, while the value between them cannot.
- A density setting is added only when both tasks can be shown to be primary; every
  setting brings a second layout and the burden of persisting state.
- Target size criteria draw density's lower bound; the 33-pixel row passes the lowest
  threshold and falls short of the enhanced one.

## Next Step

This lesson's calculations assumed one fixed viewport height and one fixed container
width. The Grid Systems lesson found that at a 768-pixel container, no column division
met the content criteria. Both findings lead to the same question: what does a layout do
when width changes? The next lesson establishes the difference between the responsive and
adaptive approaches, computes how column count is derived from width, and shows that
breakpoints are derived from content criteria rather than device lists.
