Lesson 08 / 22
Density Decisions
Deriving information density from the task; computing records per screen, scan cost, and spacing ratio from row height.
Contents
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.
// 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.
To keep your progress and take notes, Log in
My notes
Log in to take notes.