Interface & Interaction Design
Interface and interaction design is the art and science of shaping the gap between human intention and machine response — making complex systems feel obvious.
Overview
When you glance at a well-designed interface, something remarkable happens: you don't see an interface at all. You see your goal. That invisibility — that sense of fluency and naturalness — is not accidental. It is the result of decades of research at the intersection of cognitive psychology, visual perception, and software engineering, crystallized into principles that the best designers and engineers apply deliberately.
Interface and interaction design sits at the core of HCI (Human–Computer Interaction), a discipline born in the 1980s when computers began migrating from machine rooms to desks, and from experts to everyone. Don Norman's The Design of Everyday Things (1988), Jef Raskin's work at Apple, and the founding of Xerox PARC collectively established that usability is not cosmetic — it is fundamental. A system that users cannot understand or operate is, functionally, broken, regardless of its technical elegance.
This module covers the intellectual core of that discipline: the visual principles that govern what users perceive and how, the architecture of information that shapes what users can find, the interaction patterns that set their expectations, the feedback loops that tell them whether their actions succeeded, and the design systems that allow teams to build cohesive interfaces at scale. We will treat these rigorously — with cognitive models, testable heuristics, and code — not as style advice.
You will discover that the "soft" questions of design have surprisingly precise answers, grounded in Gestalt psychology, Fitts's Law, signal detection theory, and accessibility standards. By the end, you should be able to critique an interface with the same analytical precision that a compiler engineer critiques a register-allocation strategy — and build interfaces that hold up to that same scrutiny.
Every piece of software ultimately meets a human being. No matter how algorithmically perfect a system is, if its interface imposes unnecessary cognitive load, fails to communicate state, or violates perceptual expectations, users will make errors, distrust the system, or abandon it. In safety-critical domains — aviation, medical devices, nuclear control rooms — poor interaction design has killed people. In commercial software, it costs billions in support calls, lost users, and remediation. The ACM Code of Ethics explicitly identifies harm avoidance and respect for user autonomy as professional obligations, and interface quality is directly implicated in both.
For the computer scientist specifically, interaction design matters for a second reason: it forces you to reason about your system from the outside in. The mental model a user builds of your software is not the same as your implementation model — and the gap between these models is the source of most usability failures. Learning to design well means learning to separate the conceptual model (what the user believes) from the system model (what the machine does), and to deliberately close that gap through interface choices. This outside-in perspective improves not just UI code, but API design, error messages, documentation, and the architecture of the systems themselves.
Norman's Action Cycle and the Two Gulfs
Norman's seven-stage action cycle, showing where the Gulf of Execution (translating goal into action) and Gulf of Evaluation (interpreting system response) create failure modes. Good interface design narrows both gulfs.
The concepts
01Visual Design Principles: Perception Before Aesthetics
Visual design in interfaces is not about making things look pretty. It is about exploiting the architecture of the human visual system to communicate information efficiently and accurately. The foundational framework is Gestalt psychology, a set of principles — developed in early 20th-century Germany — describing how the brain groups raw visual input into meaningful objects.
The six most important Gestalt principles for UI are:
- Proximity: Elements close together are perceived as related. Grouping form fields, buttons, or navigation items spatially tells the user they belong together semantically.
- Similarity: Elements that share visual attributes (color, shape, size, texture) are perceived as related. Use similarity to encode category membership — all primary actions in one color, all destructive actions in another.
- Continuity: The eye follows smooth lines and curves, preferring continuous forms. Alignment creates invisible lines that organize layouts without visible borders.
- Closure: The brain completes incomplete shapes. Partial borders, subtle shadows, and clipped elements are 'filled in' cognitively, allowing clean layouts with implied rather than drawn structure.
- Figure/Ground: Every visual scene is parsed into an object (figure) and a background. Contrast, size, and sharpness determine which is which. Modals, tooltips, and popovers rely on this: the modal must feel like a figure against the dimmed ground of the page beneath.
- Common Fate: Elements that move together are perceived as a unit. Animations that move a group of items reinforce their unity even if they weren't grouped statically.
Beyond Gestalt, preattentive attributes — color, size, orientation, motion, shape — are processed in parallel by the visual cortex before conscious attention is engaged. A single red item in a sea of grey items is found in O(1) time regardless of how many grey items there are; a specific word in a paragraph of text requires serial search. Interface designers exploit preattentive attributes to direct attention: the primary action button is larger and differently colored not for decoration, but to make it findable in O(1) time.
Visual hierarchy is the deliberate arrangement of elements so that more important information is seen first. It is achieved through contrast in size (larger = more important), weight (bold = more important), color (saturated = more salient), and position (top-left in Western reading order = first scanned). A page without visual hierarchy forces the user to determine importance themselves — which is cognitive work they should not have to do.
Whitespace (negative space) is not empty space. It is the visual breathing room that separates elements, reduces clutter, and makes the figure/ground relationship clear. The famous example is Apple's product pages: the generous whitespace around objects makes each object feel premium and important, while dense packing makes everything feel cheap and confusing.
/* CSS illustrating visual hierarchy and Gestalt proximity */
.card-group {
display: flex;
gap: 8px; /* proximity: cards within a group are close */
margin-bottom: 32px; /* separation: groups are far apart */
}
.primary-action {
background: #1a73e8; /* similarity: all primary actions share this color */
font-size: 1rem;
font-weight: 600;
padding: 12px 24px;
}
.destructive-action {
background: #d93025; /* similarity: all destructive actions share this color */
font-size: 1rem;
font-weight: 600;
padding: 12px 24px;
}
/* Visual hierarchy through size contrast */
.page-title { font-size: 2.5rem; font-weight: 700; color: #202124; }
.section-title { font-size: 1.5rem; font-weight: 600; color: #202124; }
.body-text { font-size: 1rem; font-weight: 400; color: #5f6368; }
02Fitts's Law and the Geometry of Interaction
Fitts's Law (1954) is one of the most empirically robust results in experimental psychology. It predicts the time to acquire a target with a pointing device:
T = a + b · log₂(1 + D/W)
where T is the movement time, D is the distance to the target, W is the width (size) of the target in the direction of movement, and a, b are empirical constants for the specific motor system and device. The quantity ID = log₂(1 + D/W) is called the Index of Difficulty, measured in bits.
Fitts's Law has profound, counterintuitive implications for interface design:
Corners and screen edges are infinitely large targets. Because the cursor physically cannot overshoot a screen edge, the effective W for a button pushed into a corner or edge is infinite. This is why macOS puts the menu bar at the very top of the screen: any upward flick of the mouse reaches it with T = a (minimum time), no precision required. Windows's decision to place the taskbar at the bottom accomplishes the same for that platform.
Target size matters more when distance is large. Doubling the width of a button always reduces acquisition time, but the benefit is largest when the target is far away. Touchscreen design must obey this especially strictly: fingers have large contact areas (10–15mm diameter), so interactive targets below ~44px (Apple's recommendation, ~7mm) become error-prone.
The pie menu is optimal under Fitts's Law. A context menu that radiates options outward from the cursor in a circle minimizes both D (every option is one step from the cursor) and maximizes apparent W (the sectors extend to the screen boundary). Linear menus, by contrast, force D to grow with each additional option. Research by Callahan et al. (1988) verified this empirically.
Keystroke-Level Modeling (KLM), developed by Card, Moran, and Newell at Xerox PARC (1980), extends this idea to full tasks. It assigns time estimates to atomic operations (K=keystroke ~230ms, P=pointing ~1.1s, H=home hands ~400ms, M=mental preparation ~1.35s) and predicts total task time by summing the sequence. KLM allows you to predict and compare interface efficiency before building anything.
For a developer, Fitts's Law shapes decisions like: should the submit button be at the bottom of a form (far from where the user just typed) or beside the last field? Should destructive buttons be deliberately small and far away (to exploit the law as a safety mechanism)? These are not aesthetic questions — they are engineering questions with quantitative answers.
# Fitts's Law: compute Index of Difficulty and predicted time
import math
def fitts_id(distance_px: float, width_px: float) -> float:
"""Index of Difficulty in bits."""
return math.log2(1 + distance_px / width_px)
def fitts_time(distance_px: float, width_px: float,
a: float = 0.2, b: float = 0.1) -> float:
"""Predicted movement time in seconds (a, b are device constants)."""
return a + b * fitts_id(distance_px, width_px)
# Compare: small button far away vs large button close
print(fitts_time(800, 40)) # far, small → ~0.93s
print(fitts_time(800, 120)) # far, large → ~0.74s
print(fitts_time(200, 120)) # close, large → ~0.43s
# Screen-edge button: W → ∞, so ID → log2(1+0) = 0, T → a
print(fitts_time(800, float('inf'))) # → 0.2s (just constant a)
03Norman's Interaction Model and the Gulfs of Execution and Evaluation
Don Norman's action cycle from The Design of Everyday Things gives us a precise vocabulary for where interface failures occur. The cycle has seven stages:
- Form the goal — the user has some desired state of the world
- Form the intention — translate the goal into a specific action plan
- Specify the action — determine the exact interface manipulation required
- Execute the action — physically perform it
- Perceive the state of the world — observe what changed
- Interpret the state — understand what the change means
- Evaluate the outcome — compare to the original goal
Norman identifies two critical gaps:
Gulf of Execution: The gap between what a user wants to do and the actions available in the interface. A user wants to "make this paragraph a title" but the interface offers only raw font size controls — the user must figure out which combination of controls achieves the semantic intent. The gulf is wide. Semantic controls (a 'Heading 1' style) close the gulf because the interface speaks the user's language.
Gulf of Evaluation: The gap between what the interface displays and the user's ability to interpret it as reflecting system state. After clicking 'save', does the file get saved? A spinning indicator, then a checkmark, closes the gulf. Silence leaves it wide open.
Norman also introduces affordances (what actions an object's properties suggest), signifiers (perceptual signals that communicate affordances), mappings (relationships between controls and their effects), feedback (communication of the result of an action), and constraints (restrictions on what actions are possible). A door handle that affords pushing (flat plate) but actually requires pulling is a signifier failure — and an extremely common one.
For software: a text field affords text entry because it looks editable. A grayed-out button signifies 'not currently actionable'. The mapping between a volume slider's position and the resulting sound level should be natural — moving right increases volume — not arbitrary. And when the user clicks 'Send', the feedback (message moves to Sent folder, send animation plays) closes the gulf of evaluation.
Conceptual models tie all of this together. Every interface implicitly teaches users a model of how the underlying system works. The desktop metaphor — files, folders, trash — gave users a conceptual model (virtual office) that mapped imperfectly but adequately onto filesystem semantics. When the conceptual model a user builds diverges from the actual system model, errors occur. The designer's job is to make the interface's projected model (what it implies) as close as possible to the designer's system model (how it works), so the user's mental model stays accurate.
# Pseudocode: designing a button state machine that closes the Gulf of Evaluation
type ButtonState = IDLE | LOADING | SUCCESS | ERROR
function handleSubmit(form):
button.setState(LOADING) # immediate feedback: action received
button.setLabel("Saving...")
button.setAriaLabel("Saving, please wait")
result = await api.save(form.data())
if result.ok:
button.setState(SUCCESS) # evaluation: it worked
button.setLabel("Saved!")
announce("Changes saved successfully") # for screen readers
after(2000ms): button.setState(IDLE)
else:
button.setState(ERROR) # evaluation: it failed
button.setLabel("Save failed — retry?")
showInlineError(result.message)
# Each state has a distinct visual appearance and label,
# so the user always knows where in the action cycle they are.
04Information Architecture: Structure Before Screen
Information architecture (IA) is the structural design of shared information environments. Before any visual design decision, IA asks: what information exists? how is it organized? how will users navigate to it? The term was popularized by Richard Saul Wurman and later rigorously defined by Morville and Rosenfeld in Information Architecture for the World Wide Web (1998).
The core components of IA are:
Organization systems — how information is classified. The fundamental insight is that there is no single 'natural' organization; every taxonomy embodies assumptions about how users will seek information. The same medical content might be organized by symptom (patient's perspective), by organ system (physician's perspective), or by treatment modality (hospital administrator's perspective). Card sorting is a user research technique for discovering which organizational scheme maps best onto user mental models: participants sort content cards into groups they find natural, and cluster analysis reveals the implicit taxonomy.
Navigation systems — how users move through the information space. The primary navigation types are: global navigation (always present, covers the whole site), local navigation (contextual, covers current section), contextual navigation (inline links to related content), and breadcrumbs (showing position in the hierarchy). The choice of navigation type encodes assumptions about whether users primarily browse (exploring) or search (seeking a specific item).
Labeling systems — the vocabulary used for categories, links, and headings. Labeling failures are among the most common IA errors: using internal jargon ('SKU Management') instead of user language ('Your Products'), or using ambiguous terms ('Resources') that different users interpret differently. Content inventory + content audit are the standard tools for systematically cataloging and evaluating existing labels.
Search systems — how users can query the information space directly. Good search requires thinking about query types (known-item search vs. exploratory search), result ranking (relevance, recency, popularity), and zero-result handling (what to show when nothing matches).
A key concept is the information scent (Pirolli & Card, 1999), borrowed from animal foraging theory. Users follow links whose labels and context suggest they are 'warm' — close to the goal. When information scent is weak (vague labels, missing context), users get lost or abandon. Strong information scent means labels are specific, predictive, and match user vocabulary.
Miller's Law (1956) introduced the famous 'seven plus or minus two' limit on working memory — roughly 5–9 chunks can be held at once. The implication for navigation menus was widely misunderstood as 'never have more than 7 menu items', but the real insight is about chunk size: users can handle any number of items if they can be grouped into a small number of meaningful chunks. A navigation bar with 3 top-level categories, each with a dropdown, is cognitively manageable even with 30 total items.
The three-click rule is a popular myth — research (Cockburn & Jones, 2002) has shown users do not abandon sites after 3 clicks. What actually matters is whether each click reduces uncertainty (the user feels they are getting closer). A 6-click path with clear information scent at each step is better than a 2-click path where the first step is a mystery.
// TypeScript: a typed navigation tree structure that encodes IA
// The tree shape IS the information architecture
type NavNode = {
id: string;
label: string; // user-facing vocabulary
path?: string; // leaf nodes have paths
children?: NavNode[]; // branch nodes have children
tags?: string[]; // for cross-cutting faceted nav
};
const siteNav: NavNode = {
id: 'root',
label: 'Site Root',
children: [
{
id: 'products',
label: 'Products', // user vocabulary, not 'SKU Catalog'
children: [
{ id: 'software', label: 'Software', path: '/products/software' },
{ id: 'hardware', label: 'Hardware', path: '/products/hardware' },
]
},
{
id: 'support',
label: 'Support',
children: [
{ id: 'docs', label: 'Documentation', path: '/support/docs' },
{ id: 'contact', label: 'Contact Us', path: '/support/contact' },
]
},
]
};
// Breadcrumb generation: traverse from root to current node
function breadcrumbs(nav: NavNode, targetId: string): NavNode[] {
function search(node: NavNode, path: NavNode[]): NavNode[] | null {
if (node.id === targetId) return [...path, node];
for (const child of node.children ?? []) {
const found = search(child, [...path, node]);
if (found) return found;
}
return null;
}
return search(nav, []) ?? [];
}
05Interaction Patterns: The Grammar of UI
Interaction patterns are reusable solutions to recurring interaction design problems — the equivalent of software design patterns, but for human-computer dialogue. Christopher Alexander's A Pattern Language (1977), about architecture and urban planning, directly inspired both software design patterns and interaction patterns.
The most important interaction patterns, and why they work:
Progressive Disclosure: Show only the information and controls needed for the current task; reveal complexity on demand. This respects Miller's limit by keeping the visible option space small. Example: a form that initially shows only 3 required fields, with an 'Advanced options' toggle that reveals 12 more. The user who needs only the basics is not overwhelmed; the power user can still access everything.
Forgiving Actions (Undo/Redo): Any destructive action should be reversible. This is not just nice-to-have — it fundamentally changes user behavior. Research shows that users explore more boldly and learn faster when they believe they can undo mistakes. The UNIX philosophy of 'move to trash' rather than 'delete' is the same pattern. From an implementation standpoint, undo/redo is best modeled as a command stack (Command pattern): each action is an object with execute() and undo() methods.
Contextual Controls: Show controls when and where they are relevant, not always. An 'edit' button that appears when you hover over a paragraph, rather than a persistent toolbar, reduces visual noise and provides proximity between the control and the content it affects (closing the gulf of execution).
Empty States: What does the interface look like before the user has done anything? An empty state is not a failure — it is an opportunity to orient the user and invite action. 'You have no projects yet. Create your first project →' is far better than a blank screen.
Inline Validation: Validate form fields as the user types or on blur (focus lost), not only on submit. This minimizes the feedback loop: the user learns about an error when the context is fresh (they just typed that field) rather than after they have forgotten which field contained which input.
Skeleton Screens: Rather than a spinner blocking the entire screen, show the structural layout of the page with placeholder elements (gray bars for text, shapes for images) as content loads. Users perceive skeleton screens as faster because they provide immediate feedback (content is coming) and allow the user to orient to the layout before content arrives.
Pagination vs. Infinite Scroll: Pagination gives users a sense of position (page 3 of 47) and makes content easily revisitable (bookmark a page). Infinite scroll eliminates friction for continuous consumption but destroys navigability. The right choice depends on the task: infinite scroll is appropriate for social feeds (discovery, no specific target); pagination is appropriate for search results (finding a specific item, comparing across items).
Affordance-based Drag and Drop: Drag handles (dots, hamburger icons) signal that an item is reorderable. Without the handle affordance, users will not discover the interaction. However, on touch screens, drag conflicts with scroll — which is why many mobile UIs use an explicit 'edit mode' with visible reorder handles, rather than always-on drag.
These patterns are not arbitrary conventions. Each one solves a specific failure mode in Norman's action cycle, reduces a measurable cognitive load, or exploits a known feature of human perception.
// Command pattern enabling Undo/Redo — foundational to forgiving design
interface Command {
execute(): void;
undo(): void;
description: string;
}
class CommandHistory {
private past: Command[] = [];
private future: Command[] = [];
execute(cmd: Command): void {
cmd.execute();
this.past.push(cmd);
this.future = []; // new action clears redo stack
}
undo(): void {
const cmd = this.past.pop();
if (!cmd) return;
cmd.undo();
this.future.push(cmd);
}
redo(): void {
const cmd = this.future.pop();
if (!cmd) return;
cmd.execute();
this.past.push(cmd);
}
canUndo(): boolean { return this.past.length > 0; }
canRedo(): boolean { return this.future.length > 0; }
}
// Example: text insert command in an editor
class InsertTextCommand implements Command {
constructor(
private doc: TextDocument,
private position: number,
private text: string
) {}
description = `Insert "${this.text}"`;
execute() { this.doc.insert(this.position, this.text); }
undo() { this.doc.delete(this.position, this.text.length); }
}
06Feedback, Responsiveness, and Perceived Performance
Jakob Nielsen's response time limits (1993, updated from Miller 1968) remain the most cited empirical guidelines in UI engineering:
- < 100ms: Feels instantaneous. User feels in direct control. No feedback needed.
- 100ms–1s: User notices the delay but doesn't lose focus. A visual change (color shift, cursor change) is sufficient.
- 1s–10s: User loses the thread of thought. A progress indicator is required to signal that work is proceeding.
- > 10s: User wants to do something else. The operation should run in the background with a notification on completion.
These are not arbitrary thresholds. The 100ms limit corresponds to the human flicker-fusion threshold for direct manipulation (moving a physical slider feels like it responds to your hand only if feedback is < 100ms). The 1s limit corresponds to the 'unit task' boundary in cognitive psychology — the length of a single conscious action.
The key insight: user experience is dominated by perceived performance, which can be manipulated independently of actual performance. Research by Doherty and Thadhani (1982) established that response time under 400ms produces a qualitatively different (better) work style — users enter a state of flow. More recently, research on mobile apps showed that optimistic updates (update the UI immediately, send the request in the background, roll back on failure) make apps feel dramatically faster even though total latency is unchanged.
Progress indicators must be chosen carefully. An indeterminate spinner communicates 'something is happening, but I don't know how long'. A determinate progress bar communicates 'I know how far we are'. Use indeterminate indicators only when progress truly cannot be estimated; users find them more frustrating than an accurate progress bar because they eliminate the ability to decide 'is it worth waiting?' A step indicator ('Step 2 of 5') provides the same psychological benefit as a progress bar for multi-stage processes.
Animation and transitions serve a functional purpose beyond aesthetics. They provide continuity cues (where did that element go?), maintain context during state changes (what is this new screen — where am I relative to where I was?), and signal affordances (a button that squishes on tap confirms the tap was received). The ideal duration for interface transitions is 200–500ms — fast enough to feel snappy, slow enough for the brain to register what changed. Animations longer than ~500ms start to feel sluggish; shorter than ~100ms are imperceptible.
Error messages are a critical, often botched form of feedback. A well-designed error message must:
- State clearly what went wrong (not 'Error code -1' or 'Something went wrong').
- Explain why it went wrong, if not obvious.
- Tell the user what to do to fix it or proceed. The message should be in the user's vocabulary, not the system's. 'Your session has expired. Please sign in again.' is good. 'Error: JWT validation failed with status 401' is not. This is not dumbing down — it is closing the gulf of evaluation by making system state legible to the user.
// React hook: optimistic update with rollback for perceived performance
import { useState, useCallback } from 'react';
function useOptimisticToggle(initialValue: boolean, onSave: (v: boolean) => Promise<void>) {
const [value, setValue] = useState(initialValue);
const [error, setError] = useState<string | null>(null);
const toggle = useCallback(async () => {
const prev = value;
setValue(!prev); // optimistic update: UI changes immediately
setError(null);
try {
await onSave(!prev); // actual async request
} catch (err) {
setValue(prev); // rollback on failure
setError('Could not save change. Check your connection and try again.');
}
}, [value, onSave]);
return { value, toggle, error };
}
// Usage: a like button that feels instant
// <LikeButton> calls toggle() → UI flips immediately,
// request fires in background, rolls back only if it fails.
// Users experience ~0ms latency for the happy path.
07Heuristic Evaluation and Nielsen's 10 Usability Heuristics
Heuristic evaluation (Nielsen & Molich, 1990) is a usability inspection method in which 3–5 expert evaluators independently assess an interface against a set of recognized usability principles (heuristics), then aggregate findings. It was specifically designed to be cheap and effective without requiring end users — making it the most practical tool for the early design and development phases.
Nielsen's 10 Usability Heuristics (1994, updated 2020) remain the most widely used framework:
- Visibility of system status: Always tell the user what is happening. (Progress indicators, status bars, active state highlights.)
- Match between system and real world: Use language, concepts, and conventions that match the user's world, not internal technical terms.
- User control and freedom: Support undo, redo, and cancellation. Users make mistakes; the interface must not punish exploration.
- Consistency and standards: Follow platform conventions. 'Ctrl+Z' means undo everywhere. Users should not have to wonder whether different words/icons mean the same thing.
- Error prevention: Design to prevent errors before they happen. Confirm dialogs for irreversible actions. Disable options that are not currently valid. Gray out rather than hide.
- Recognition over recall: Minimize memory load. Make options visible. Users should not have to remember information from one screen to use it in another.
- Flexibility and efficiency of use: Support power users with shortcuts (keyboard, macros, gestures) without complicating the interface for novices. Accelerators bridge the gap between novice and expert workflows.
- Aesthetic and minimalist design: Every element that is not essential is competing with the essential elements for attention. Remove it.
- Help users recognize, diagnose, and recover from errors: Error messages must be in plain language, explain the problem precisely, and constructively suggest a solution.
- Help and documentation: Even well-designed systems sometimes require documentation. Help should be easy to search, focused on the user's task, and concrete.
Severity is rated on a 0–4 scale (0=not a problem, 4=usability catastrophe), allowing teams to triage issues. Research shows that 5 evaluators find roughly 75% of all heuristic violations; beyond 5, the return on additional evaluators drops sharply.
Contrast with usability testing: Heuristic evaluation is fast and cheap but relies on expert judgment; usability testing (observing real users attempting real tasks) is more expensive but reveals actual failure modes that experts miss. The two methods are complementary, not competing.
08Accessibility: Designing for the Full Range of Human Ability
Accessibility (a11y) is not a bolt-on feature or a legal checkbox — it is a design quality that benefits all users. The curb-cut effect is the canonical demonstration: wheelchair ramps at street curbs were mandated for mobility-impaired users, but turned out to benefit parents with strollers, delivery workers with carts, and cyclists. Similarly, captions (designed for deaf users) are used by millions of people watching video in noisy environments; high-contrast modes (designed for low-vision users) help anyone in bright sunlight.
The Web Content Accessibility Guidelines (WCAG) are the authoritative technical standard, currently at version 2.2 (with 3.0 in development). They organize requirements under four principles — the POUR framework:
- Perceivable: Information must be presentable to users in ways they can perceive. Images need text alternatives (alt text). Audio needs captions. Color cannot be the only carrier of information (color-blind users will miss it).
- Operable: The interface must be operable without a mouse. Every interactive element must be keyboard-reachable (via Tab) and activatable (via Enter/Space). Focus must be visually indicated (the focus ring). No time limits unless strictly necessary.
- Understandable: Text must be readable (language declared, unusual words defined). Interface behavior must be predictable (no unexpected context changes on input focus). Error identification must be specific.
- Robust: Content must be interpreted by a wide variety of assistive technologies. This is primarily about semantic HTML: using
<button>for buttons (not<div class='button'>),<nav>for navigation, heading levels in document order, ARIA roles only when native semantics are insufficient.
ARIA (Accessible Rich Internet Applications) fills the gaps for complex interactive widgets that have no HTML equivalent: tab panels, comboboxes, tree views, carousels. The key ARIA attributes are role (what is this element?), aria-label / aria-labelledby (what is it called?), aria-describedby (what additional description applies?), and states like aria-expanded, aria-checked, aria-disabled.
Screen reader mental model: A screen reader serializes the 2D visual layout into a 1D linear stream. The user navigates by jumping between headings, landmarks, links, and form controls. A page that relies entirely on visual positioning (absolute coordinates, grid layout with no semantic structure) is a flat, undifferentiated stream to a screen reader user. Structure must be encoded both visually and semantically.
The WCAG conformance levels are A (minimum), AA (required by most laws including ADA, AODA, EU Web Accessibility Directive), and AAA (enhanced, not always achievable). WCAG 2.1 AA is the standard target for professional web development.
<!-- Good vs. bad accessibility: a form example -->
<!-- BAD: no labels, no error messages, div-as-button -->
<div class="btn" onclick="submit()">Submit</div>
<input type="text" placeholder="Email" />
<!-- GOOD: semantic HTML, explicit labels, ARIA for error state -->
<form novalidate aria-label="Newsletter signup">
<div class="field">
<label for="email">Email address</label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
aria-required="true"
aria-describedby="email-error"
aria-invalid="true"
/>
<span id="email-error" role="alert">
Please enter a valid email address (e.g., you@example.com)
</span>
</div>
<!-- <button> is keyboard-focusable and activatable by default -->
<button type="submit">Subscribe to newsletter</button>
</form>
<!-- role="alert" causes screen readers to announce the error
immediately without requiring the user to navigate to it. -->
09Design Systems: Scaling Consistency
A design system is the single source of truth for a product's visual and interactive language — the set of reusable components, design tokens, guidelines, and governance processes that allow multiple teams to build cohesive product experiences without reinventing (or, more dangerously, slightly-differently-inventing) every button, color, and spacing unit.
The anatomy of a design system has three layers:
-
Foundation / Tokens: The primitive values of the visual language — color palette, typographic scale, spacing scale, border radius, elevation (shadow) levels. Design tokens are named constants that map semantic meaning to values:
--color-action-primary: #1a73e8,--spacing-medium: 16px,--elevation-raised: 0 2px 6px rgba(0,0,0,0.15). Tokens are the bridge between design tools (Figma) and code (CSS custom properties, Tailwind config, Android themes). -
Components: Reusable UI building blocks that implement the interaction patterns and visual language. A Button component is not just visual styling — it encodes the states (default, hover, active, focus, disabled, loading), the keyboard behavior, the ARIA attributes, and the click handling. Every team that uses the system gets all of that for free. Brad Frost's Atomic Design methodology (atoms → molecules → organisms → templates → pages) provides one mental model for organizing components.
-
Patterns / Guidelines: Documentation for when and how to use components together to solve common design problems — how to build a form, how to handle empty states, how to communicate errors. Without this layer, teams use components in inconsistent, semantically wrong ways even when the components themselves are identical.
The consistency argument: A user who learns that primary action buttons are always blue in your product can rely on that signal throughout. If one team makes their primary button green, users must re-evaluate every button on every screen. Consistency is not aesthetic conformity — it is information encoding. The visual language carries meaning, and inconsistency is noise that degrades the signal.
The efficiency argument: Recreating a DatePicker from scratch is 2–3 days of engineering time (accessibility, localization, mobile touch behavior, all the edge cases). A shared component created once and maintained by a dedicated team amortizes that cost across every team that uses it. Google's Material Design, IBM's Carbon Design System, and Shopify's Polaris are the canonical examples of large-scale design systems.
Versioning and breaking changes are the hard part. A design system component is an API — changing a prop name or default behavior breaks every consumer. Semantic versioning, changelog discipline, and codemods for migrations are the engineering tools that make this manageable.
/* Design tokens in CSS custom properties — the foundation layer */
:root {
/* Color tokens: semantic, not literal */
--color-background-primary: #ffffff;
--color-background-secondary: #f8f9fa;
--color-text-primary: #202124;
--color-text-secondary: #5f6368;
--color-action-primary: #1a73e8;
--color-action-danger: #d93025;
--color-border-default: #dadce0;
/* Spacing scale: 4px base unit */
--space-1: 4px; --space-2: 8px; --space-3: 12px;
--space-4: 16px; --space-6: 24px; --space-8: 32px;
/* Typographic scale */
--text-xs: 0.75rem; --text-sm: 0.875rem;
--text-base: 1rem; --text-lg: 1.125rem;
--text-2xl: 1.5rem; --text-4xl: 2.25rem;
/* Elevation */
--shadow-sm: 0 1px 3px rgba(0,0,0,0.12);
--shadow-md: 0 4px 12px rgba(0,0,0,0.15);
--shadow-lg: 0 8px 24px rgba(0,0,0,0.18);
}
/* Component uses tokens, not literals — one edit to token changes everything */
.button-primary {
background: var(--color-action-primary);
color: var(--color-background-primary);
padding: var(--space-2) var(--space-4);
font-size: var(--text-sm);
border-radius: 4px;
}
10Typography and Color: The Load-Bearing Elements
Typography and color are the two most load-bearing elements in visual communication — they carry meaning even before the user reads a word or recognizes an icon.
Typography in interfaces is governed by several principles:
Typographic scale: A limited set of font size/weight combinations that form a visual hierarchy. Arbitrary sizes (17px, 23px, 31px) create incoherent pages; a consistent modular scale (based on a ratio like 1.25 or 1.5) creates pages where the hierarchy reads immediately. The scale should have at most 5–6 levels for an interface (as opposed to a book).
Measure (line length): The optimal measure for reading comprehension is 45–75 characters per line. Lines that are too long cause the eye to lose its place when returning to the left margin; lines that are too short break rhythm and cause excessive hyphenation. In CSS: max-width: 65ch is a precise way to enforce this.
Leading (line height): For body text, 1.4–1.6× the font size. For headings, 1.1–1.3× (tighter, because headings are read as units, not scanned). Insufficient leading makes text feel dense and oppressive; excessive leading makes it feel disconnected.
System fonts vs. web fonts: System fonts (San Francisco on macOS/iOS, Segoe UI on Windows, Roboto on Android) load instantly and look native. Web fonts add 50–300KB of network transfer and can cause FOUT (Flash of Unstyled Text) or FOIT (Flash of Invisible Text). Use font-display: swap to mitigate.
Color in interfaces must be understood as both a perceptual and semantic system:
Contrast ratio: The WCAG minimum for normal text is 4.5:1 (AA) and 7:1 (AAA) against its background. Light gray text on white — ubiquitous in modern flat design — frequently fails this threshold and is unreadable for users with low vision or in bright environments. The formula uses the relative luminance of each color.
Color blindness: 8% of males and 0.5% of females have some form of color vision deficiency. Red-green color blindness (deuteranopia/protanopia) is most common. Never use red vs. green alone to encode meaning (error vs. success); always add a second channel (icon, text, position).
Color as information vs. decoration: Saturation and hue attract attention. Every use of a distinct color is an implicit claim that 'this is different from everything else'. If 12 elements on a page each have a different color, the color carries no information — it is visual noise. Reserve distinct colors for distinct semantic categories, and use at most 5–7 distinct hues in any interface.
/* Checking WCAG contrast ratio in JavaScript */
function relativeLuminance(r: number, g: number, b: number): number {
// r, g, b in [0, 255]
const sRGB = [r, g, b].map(c => {
const s = c / 255;
return s <= 0.04045 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
});
return 0.2126 * sRGB[0] + 0.7152 * sRGB[1] + 0.0722 * sRGB[2];
}
function contrastRatio(
fg: [number,number,number],
bg: [number,number,number]
): number {
const L1 = relativeLuminance(...fg);
const L2 = relativeLuminance(...bg);
const lighter = Math.max(L1, L2);
const darker = Math.min(L1, L2);
return (lighter + 0.05) / (darker + 0.05);
}
// Example
const ratio = contrastRatio([95, 99, 104], [255, 255, 255]); // gray on white
console.log(ratio.toFixed(2)); // → ~3.28 — FAILS WCAG AA (need ≥ 4.5)
const good = contrastRatio([32, 33, 36], [255, 255, 255]); // dark on white
console.log(good.toFixed(2)); // → ~14.7 — passes AAA
11Mobile and Touch Interaction Design
Touch interfaces introduced a qualitatively different interaction model from mouse-and-keyboard that cannot be addressed by simply making things bigger. Understanding the differences is essential for designing across platforms.
The physical constraints of touch: A fingertip has a contact patch of roughly 10–15mm and provides no hover state. This has three major consequences:
- No hover: Every affordance that was communicated via hover (tooltip, highlight, cursor change) must be communicated in the static state or moved to another interaction.
- Fat finger problem: Targets must be at least 44×44 logical pixels (Apple HIG) / 48×48 dp (Material Design). Sub-standard targets cause tap errors that users experience as unresponsiveness or incorrect behavior.
- Occlusion: The user's finger covers the element they are tapping, making fine-grained feedback (e.g., showing a color change under the finger) invisible. Feedback must appear near but not under the fingertip.
Touch gestures as a vocabulary: Tap (select/activate), double-tap (zoom/select word), long press (context menu/mode switch), swipe (navigate/dismiss/reveal), pinch-to-zoom (scale), and rotate are the standard vocabulary. Each gesture has platform-specific semantics that users have learned. Introducing a novel gesture requires teaching, which is a cost.
Thumb reachability zones: On a phone held in one hand, the thumb naturally reaches the bottom half of the screen easily, the middle with extension, and the top with difficulty (or requires regrippling). This is why bottom navigation bars (iOS tab bars, Android bottom nav) became dominant over hamburger menus in the top-left corner — the target is where the thumb naturally rests.
Context and environment: Mobile users are often in motion, in poor lighting, in split attention (walking, commuting). This motivates even stronger application of progressive disclosure (show less, not more), larger targets, and high contrast.
Responsive design vs. adaptive design: Responsive design uses fluid layouts and media queries so a single codebase serves all screen sizes. Adaptive design serves different layouts (and sometimes different interaction models) to different device classes. The right choice depends on whether the interaction model differs across devices (different model → adaptive) or only the layout (same model → responsive).
/* CSS: responsive + thumb-friendly touch targets */
/* Minimum touch target, visually smaller but large hit area */
.icon-button {
width: 24px;
height: 24px;
position: relative;
}
.icon-button::before {
content: '';
position: absolute;
inset: -12px; /* expands hit area to 48x48px without visual change */
}
/* Bottom-anchored navigation for one-hand reach */
.bottom-nav {
position: fixed;
bottom: 0;
left: 0; right: 0;
display: flex;
justify-content: space-around;
padding-bottom: env(safe-area-inset-bottom); /* iPhone notch/home indicator */
height: 56px;
background: var(--color-background-primary);
border-top: 1px solid var(--color-border-default);
}
/* Media query: adapt layout, not just size */
@media (min-width: 768px) {
.bottom-nav { display: none; } /* replaced by sidebar nav on tablet/desktop */
.sidebar-nav { display: flex; flex-direction: column; }
}
Key insights
- ✦Interface design is not decoration — it is engineering decisions grounded in cognitive psychology, with measurable outcomes in user performance and error rates.
- ✦Fitts's Law makes target size and distance engineering constraints, not style choices: the formula T = a + b·log₂(1 + D/W) predicts pointing time and should inform button sizing, placement, and the use of screen edges.
- ✦Norman's gulfs of execution and evaluation locate where interface failures happen: execution failures occur when users cannot figure out how to express their intent; evaluation failures occur when they cannot interpret system feedback.
- ✦Preattentive attributes (color, size, motion, orientation) are processed in parallel before conscious attention — exploiting them lets designers direct attention in O(1) time, not O(n).
- ✦Perceived performance can be engineered independently of actual performance: optimistic updates, skeleton screens, and immediate feedback can make slow operations feel fast.
- ✦Accessibility (a11y) is not a special case — the POUR framework (Perceivable, Operable, Understandable, Robust) defines qualities every interface should have, and accessibility features routinely benefit the general user population.
- ✦Design systems are APIs with all the same versioning, documentation, and breaking-change concerns — treating them as engineering artifacts (not just style guides) is what makes them scale.
- ✦Information architecture is the structural layer beneath visual design: the taxonomy, navigation, and labeling of a system determine whether users can find anything, regardless of how beautiful the individual screens are.
Common pitfalls
- ⚠Using color as the ONLY differentiator between states (error vs. success, required vs. optional) — always add a second encoding channel (icon, text, position) for color-blind users and users in bright environments.
- ⚠Designing only for the happy path: empty states, loading states, error states, and partial failure states are often forgotten and discovered only in production, where they create poor first impressions and user confusion.
- ⚠Confusing 'minimalism' with 'no feedback' — removing spinners, progress bars, and confirmation messages in the name of clean design leaves users unsure whether their actions succeeded.
- ⚠Misapplying Miller's Law: the limit on working memory does not mean 'never show more than 7 items'; it means organize items into meaningful chunks of manageable size.
- ⚠Using ARIA attributes to fix non-semantic HTML ('div soup') instead of writing semantic HTML in the first place — native HTML elements already carry the correct roles and keyboard behavior; ARIA is for augmentation, not replacement.
- ⚠Optimizing for discoverability at the expense of efficiency for experienced users: a system that explains everything on-screen for novices may be cluttered and slow for experts. Progressive disclosure and keyboard shortcuts bridge this gap.
- ⚠Treating responsive design as purely a layout problem and ignoring interaction model differences: hover-based affordances, drag interactions, and precise click targets all break on touch and require genuine redesign, not just CSS resizing.
- ⚠Measuring usability by what users say rather than what they do: users are unreliable self-reporters of their own behavior (they often cannot explain why they struggled). Observational usability testing, not surveys, reveals the real failure modes.
Practice
- 01medium
Conduct a heuristic evaluation: pick any widely-used web application (e.g., a university registration system, a local government website, or an e-commerce checkout). Evaluate it against all 10 of Nielsen's heuristics. For each violation you find, write a one-paragraph finding that (a) names the heuristic violated, (b) describes the specific interface element that violates it, and (c) proposes a concrete redesign that would fix it. Rate each finding on the 0–4 severity scale and justify the rating.
- 02hard
Implement a keyboard-accessible, screen-reader-compatible tab panel widget in plain HTML, CSS, and JavaScript — without using any UI library. The widget must: (a) implement the ARIA Authoring Practices Guide tab pattern correctly (roles, aria-selected, aria-controls, keyboard navigation with arrow keys), (b) pass WCAG 2.1 AA contrast requirements for all states (use the relativeLuminance formula from the module), and (c) work correctly when CSS is disabled (the content must still be readable in DOM order).
- 03medium
Apply Keystroke-Level Modeling (KLM) to compare two designs for the same task. Task: 'rename the currently selected file in a file manager.' Design A: right-click → context menu → 'Rename' → type new name → Enter. Design B: press F2 → type new name → Enter. List every KLM operation for each design (K, P, H, M as defined in Card, Moran & Newell), sum the predicted times, and compute the speedup ratio. Then propose a Design C that is faster still, and explain why.
- 04medium
Design a complete information architecture for a community library's website. Deliverables: (a) a card-sort study design — what cards would you give participants, how many participants, what would you analyze? (b) a resulting site map (hierarchical tree of pages/sections with labels in user vocabulary, not library jargon), and (c) for three representative user tasks ('reserve a book I know the title of', 'find events for children this weekend', 'renew my library card online'), trace the optimal navigation path and identify any point where information scent might be weak.
- 05easy
Build a 'progressive disclosure' settings panel in React (or any component framework): a compact view showing only 3 essential settings, with a 'Show advanced settings' toggle that smoothly reveals 8 more settings. Requirements: (a) the transition must use CSS animation at 200–300ms (not a hard show/hide), (b) the expanded/collapsed state must be communicated to screen readers via aria-expanded and aria-controls, (c) focus must move logically when the panel expands, and (d) the panel state must survive React re-renders (persist in state, not just DOM).
- 06easy
Analyze the typography of two real interfaces (your choice) using the principles in this module. For each interface: measure the contrast ratio of body text, heading text, and placeholder text (use browser DevTools color picker + the luminance formula). Check the measure (characters per line) of the main content column. Identify the type scale (list all font sizes used). Then write a 300-word critical assessment: what does the typography communicate about the intended audience and use context? What would you change and why?
Resources
The canonical text introducing affordances, signifiers, mental models, and the action cycle. Required reading.
Nielsen Norman Group — the authoritative, regularly-updated source for the 10 heuristics.
The W3C technical standard. The 'Understanding WCAG 2.2' companion document explains each criterion with examples.
The W3C reference for implementing accessible interactive widgets (tabs, dialogs, trees, comboboxes) correctly.
The definitive IA reference covering organization, navigation, labeling, and search systems.
Brad Frost's methodology for structuring design systems from atoms to pages. Free to read online.
The standard academic HCI textbook covering cognitive models, design methods, and evaluation techniques rigorously.
Matthew Butterick's excellent online book covering typography for screens and documents with concrete, actionable guidance.
Google's Material Design 3 — a comprehensive design system specification covering components, motion, color, typography, and accessibility. Excellent for seeing how principles are applied at scale.
A rigorous, quantitative approach to interface design from the creator of the original Macintosh project. Introduces GOMS and the Canon concept.
The most thorough academic treatment of Fitts's Law applied to HCI, covering both theory and empirical validation.
Jon Yablonski's concise visual reference for the psychological principles underlying UX — Fitts, Miller, Hick's Law, and more, each with practical application guidance.
Checkpoints — you can now…
- ✓You can identify violations of at least 6 of Nielsen's 10 heuristics in a real interface and articulate which heuristic each violates and why.
- ✓You can apply Fitts's Law to justify a specific button size or placement decision, computing the predicted acquisition time and explaining how screen-edge placement affects target width.
- ✓You can trace a user's failure through Norman's action cycle and locate it as a Gulf of Execution failure (cannot express intent) or Gulf of Evaluation failure (cannot interpret feedback), then propose a specific interface change to close that gulf.
- ✓You can write semantically correct, keyboard-accessible HTML for at least three interactive patterns (form with inline validation, button with loading state, navigation with landmark roles) and verify them with a screen reader.
- ✓You can compute the WCAG contrast ratio between two colors using the relative luminance formula and determine whether the pairing meets AA or AAA requirements.
- ✓You can design a two-level information architecture (site map with labeled sections) for a real-world domain using user vocabulary rather than internal jargon, and justify the top-level categories by reference to user mental models.
- ✓You can explain the difference between responsive and adaptive design strategies, give an example of a mobile interaction pattern (thumb zones, gesture vocabulary, no-hover state) that cannot be solved by CSS alone, and propose a concrete solution.
- ✓You can define design tokens, explain their role in a design system, and write a small CSS/JSON token file that bridges a color, spacing, and typographic scale — then trace how a change to a single token propagates to all components that use it.