Lesson 02 / 22
Proximity and Grouping
How relationship is declared through space; grouping is established by spacing ratio rather than absolute space, and nested grouping levels are audited numerically.
Contents
The previous lesson dealt with separating elements from one another: which element is read first, and on which channels that order is expressed. The interface’s second job is the reverse. In a catalog record, the title, the author’s name, and the shelf code are drawn separately but belong to the same book. The next record’s title sits only a few pixels below and belongs to a different book. On screen, what tells these two situations apart?
The answer is not a line or a frame but space. This lesson shows how space establishes a relationship, why that relationship depends not on an absolute pixel value but on the ratio between gaps, and how that ratio is audited.
Proximity Declares a Relationship
Proximity is the tendency for elements standing close to one another to be perceived as a single unit. This tendency is a member of a group known in perceptual psychology as the Gestalt principles, which also includes elements that look alike being perceived together (similarity) and elements sharing a common background or frame being perceived together (common region).
These principles matter for interface design in a practical, not a theoretical, sense: they do not offer a choice, they impose a constraint. The moment elements are placed on a plane, they are grouped. The designer’s decision is not “should I group these” but “does the perceived grouping match the intended grouping.” When no space is assigned, grouping does not disappear; a random grouping settles in instead.
There is a ranking of strength among the proximity principles. When two elements are close but differ in color, proximity beats similarity: the elements are read as a single group. In a catalog record, if the title is dark and bold while the author’s name is pale and normal weight, the two are still perceived as a single record when only 4 pixels separate them. This means hierarchy and grouping do not coincide: elements inside a group can differ in weight from one another; what carries the group’s identity is the space.
Grouping Is Established by Ratio, Not Absolute Space
Proximity is a relative measure. The sentence “24 pixels of space separates the records” is neither true nor false on its own; it cannot be evaluated without knowing how many pixels of space sit inside the record. If the internal spacing is 4 pixels, 24 pixels is a clear boundary; if the internal spacing is 20 pixels, the same 24 pixels separates nothing.
Making this auditable requires a criterion. This course adopts the following one: a gap counts as a group boundary if it is at least twice the smallest gap in the same stack. The program below tests two different spacing decisions for the catalog results list against this criterion.
// 02-grouping.mjs — checks grouping in a vertical stack by gap ratio // Two rows of the catalog result list: each record carries a title + author + metadata. // Each item is given as (name, height, topGap); topGap is its distance from the previous item. const designA = [ { name: "record-1 title", height: 24, topGap: 0, group: 1 }, { name: "record-1 author", height: 20, topGap: 4, group: 1 }, { name: "record-1 metadata", height: 18, topGap: 4, group: 1 }, { name: "record-2 title", height: 24, topGap: 24, group: 2 }, { name: "record-2 author", height: 20, topGap: 4, group: 2 }, { name: "record-2 metadata", height: 18, topGap: 4, group: 2 }, ]; const designB = [ { name: "record-1 title", height: 24, topGap: 0, group: 1 }, { name: "record-1 author", height: 20, topGap: 12, group: 1 }, { name: "record-1 metadata", height: 18, topGap: 12, group: 1 }, { name: "record-2 title", height: 24, topGap: 16, group: 2 }, { name: "record-2 author", height: 20, topGap: 12, group: 2 }, { name: "record-2 metadata", height: 18, topGap: 12, group: 2 }, ]; // Course criterion: a gap counts as a group boundary if it is SEPARATION_RATIO times // the smallest gap in the stack. Below a ratio of 2 the boundary is ambiguous. const SEPARATION_RATIO = 2; function groupItems(items) { const gaps = items.slice(1).map((o) => o.topGap); const smallest = Math.min(...gaps); const groups = [[items[0].name]]; const ratios = []; for (let i = 1; i < items.length; i++) { const ratio = items[i].topGap / smallest; ratios.push({ name: items[i].name, gap: items[i].topGap, ratio }); if (ratio >= SEPARATION_RATIO) groups.push([items[i].name]); else groups[groups.length - 1].push(items[i].name); } return { smallest, ratios, groups }; } function report(title, items) { const { smallest, ratios, groups } = groupItems(items); const intended = new Set(items.map((o) => o.group)).size; console.log(`${title} (smallest gap: ${smallest}px, threshold ratio: ${SEPARATION_RATIO})`); for (const o of ratios) { const boundary = o.ratio >= SEPARATION_RATIO ? "BOUNDARY" : "in group"; console.log( ` ${o.name.padEnd(18)} above ${String(o.gap).padStart(2)}px ratio ${o.ratio .toFixed(2) .padStart(5)} ${boundary}` ); } console.log(` intended group count: ${intended} perceived group count: ${groups.length}`); groups.forEach((g, i) => console.log(` group ${i + 1}: ${g.join(", ")}`)); console.log(""); } report("design A in-group 4px / separator 24px", designA); report("design B in-group 12px / separator 16px", designB);
design A in-group 4px / separator 24px (smallest gap: 4px, threshold ratio: 2)
record-1 author above 4px ratio 1.00 in group
record-1 metadata above 4px ratio 1.00 in group
record-2 title above 24px ratio 6.00 BOUNDARY
record-2 author above 4px ratio 1.00 in group
record-2 metadata above 4px ratio 1.00 in group
intended group count: 2 perceived group count: 2
group 1: record-1 title, record-1 author, record-1 metadata
group 2: record-2 title, record-2 author, record-2 metadata
design B in-group 12px / separator 16px (smallest gap: 12px, threshold ratio: 2)
record-1 author above 12px ratio 1.00 in group
record-1 metadata above 12px ratio 1.00 in group
record-2 title above 16px ratio 1.33 in group
record-2 author above 12px ratio 1.00 in group
record-2 metadata above 12px ratio 1.00 in group
intended group count: 2 perceived group count: 1
group 1: record-1 title, record-1 author, record-1 metadata, record-2 title, record-2 author, record-2 metadata
Both designs share the same goal: two records, two groups. Design A produces it; design B does not. What stands out is that design B is more spacious. Its total spacing is greater — it leaves 16 pixels between records — and yet it erases the record boundary. Adding space does not improve grouping; differentiating space does.
This also explains why spacing decisions cannot be made one at a time. The decision to place 16 pixels between records cannot be evaluated in isolation, because its meaning depends on neighboring decisions. Spacing decisions are made as a set.
Nested Grouping Levels
The catalog screen does not have a single grouping level. The title and the author’s name are grouped at one level, record blocks at a level above that, records at a level above that, and the screen’s sections at the top. Every level must be distinguishable from the level below it; otherwise one rung of the hierarchy becomes invisible.
// 02-nested.mjs — checks the gap ratio of nested grouping levels // Four grouping levels on the catalog screen, innermost to outermost. const levels = [ { name: "within row (title-author)", gap: 4 }, { name: "blocks within record", gap: 8 }, { name: "between records", gap: 24 }, { name: "between sections", gap: 48 }, ]; const SEPARATION_RATIO = 2; console.log("level gap ratio to level below status"); for (let i = 0; i < levels.length; i++) { const l = levels[i]; if (i === 0) { console.log(`${l.name.padEnd(26)} ${String(l.gap).padStart(4)}px ${"-".padStart(20)} base`); continue; } const ratio = l.gap / levels[i - 1].gap; const status = ratio >= SEPARATION_RATIO ? "separates" : "AMBIGUOUS"; console.log( `${l.name.padEnd(26)} ${String(l.gap).padStart(4)}px ${ratio.toFixed(2).padStart(20)} ${status}` ); }
level gap ratio to level below status within row (title-author) 4px - base blocks within record 8px 2.00 separates between records 24px 3.00 separates between sections 48px 2.00 separates
Four levels, a base spacing of 4 pixels, an outermost spacing of 48 pixels. Every ratio between them sits above two, so every level is distinguishable from the one below it. The real finding here is not the numbers themselves but their multiplicative progression: 4, 8, 24, 48. An additive sequence (4, 8, 12, 16) cannot do the same job, because toward the outer levels the ratios rapidly approach one.
This observation also sets a limit on the number of grouping levels. If the base spacing is 4 pixels and every level must be at least twice the one below it, six levels require pixels at the outermost level. Considering how expensive 128 vertical pixels are on a screen, the practical number of grouping levels turns out to sit around four. As with hierarchy levels, the fix here is not adding a level but removing one that is not needed.
Space or a Frame
The common-region principle is a second way to group: enclosing elements in a frame or giving them a shared background color also turns them into a single unit. This route is stronger than proximity — a frame beats proximity: two elements that are far apart inside a box are perceived as more related than a nearby element outside the box.
Being stronger does not make it the default choice. A frame’s cost is visual noise. If every record in a twenty-record results list is framed, 20 rectangles — 80 lines — are added to the screen. None of these lines carries information; every one of them just declares the record boundary. If the same boundary were declared with space, no line would be added to the screen at all. Space is the only grouping tool that works with zero ink.
The criterion can be written as follows: common region is reserved for establishing a relationship that proximity cannot build. There are three situations where proximity falls short. The first is when elements are not separated horizontally and vertically; giving a table’s rows space would inflate row height, so separating them with a background color can be cheaper. The second is when a group carries a function different from the rest of the screen; the section holding the borrowing action is an action area, and separating it from the reading area with space alone loses information. The third is when the group is a scrollable area; a scroll area with no visible boundary hides where the content ends.
The Mislinked Label
The most expensive form of a proximity error appears in the section holding the search field. The catalog interface has three filter fields: publication year, language, and material type. Above each field is a label, and below it a description line.
If the space between the label and the field is 8 pixels, the space between the field and the description is 8 pixels, and the space between the description and the next label is 12 pixels, the ratio to the smallest gap is 12 / 8 = 1.5, which stays below the threshold. The result is three separate filters turning into a single block; the reader cannot tell which description belongs to which field from the space and has to find out by trial.
The correct arrangement is to bind the label to the field and separate the group from the outside: label–field 4 pixels, field–description 4 pixels, between groups 24 pixels. The ratio becomes 24 / 4 = 6. This arrangement looks more “cramped” on paper, but it reads more clearly on screen, because the cramping sits inside the group while the spaciousness sits between groups.
The same rule applies to the label’s position. When the label is placed to the left of the field, the horizontal space between the label and its own field must be smaller than the vertical space between the label and the next row. In a grouping that operates on two axes, the ratio criterion is tested separately on each axis.
Summary
- Proximity is the perception of nearby elements as a single unit; elements are grouped the moment they are placed on a plane, so the question is not whether grouping exists but whether it matches the intended grouping.
- Grouping is established by the ratio between neighboring gaps, not by an absolute spacing value; this course’s criterion is that a group boundary is at least twice the smallest gap.
- Adding space does not improve grouping; differentiating space does. A design with more total spacing can group more weakly.
- Nested grouping levels progress multiplicatively; an additive sequence erases boundaries at the outer levels because it drives the ratio toward one.
- Common region is stronger than proximity but carries an ink cost; it is reserved for relationships proximity cannot build.
- Spacing decisions are made as a set rather than one at a time, because a gap’s meaning depends on its neighboring gaps.
Next Step
This lesson dealt with establishing relationships. What remains is establishing distinction with restraint. In the previous two lessons, distinction was always treated in one direction: bringing an element forward. But emphasis is a budget; every emphasized element on screen reduces the share left for the other emphasized elements. The next lesson computes visual weight from area and luminance difference, extracts the emphasis shares on the catalog screen, and uses numbers to show why three primary actions leave none of them primary.
To keep your progress and take notes, Log in
My notes
Log in to take notes.