Component design: the Rule of 3
A cheap stress test that surfaces translation, zoom and future use-case fragility before a component ships.
The problem
When a component is first built, the team rarely sees every use case it will eventually have to cover. One feature triggers the need, the deadline is short, and translation, browser zoom and the next team’s requirements are all “later” problems.
When later arrives. The component might need an extra action, a menu, DOM changes, a longer label or more images. The additions can be a breaking change to the code API or Figma composition. Every consuming team then has to react; in effect, the cost lands outside the team that took the shortcut.
The Rule of 3
The Rule of 3 is a cheap exercise that surfaces those breakages before the component ships. Triple three things:
- Three times the copy — replace every text layer with capital W’s — three per original character, plus two. W is the widest Latin glyph, so the result models the worst case for translation, text scaling and unexpectedly long labels.
- Three times the functions — triple every action, button and link. Decide how the component absorbs the overflow.
- Three times the content — triple every content slot (image, tag, paragraph, icon). Decide what wraps, what caps, and what gets a “view more”.
What you get when you’ve done it:
- Responsiveness across viewport sizes, devices and browser zoom
- Headroom for translation, where copy lengths vary
- Flexibility for additional use cases, supporting more functions and controls over time
The rest of this guide runs the rule through two real components from this site, end-to-end.
Worked example A — CaseStudyCard
CaseStudyCard is the card used on the homepage and case-studies index. It has featured and secondary variants, a cover plate or image, title, description, tag list, year, and an optional stats row.
Baseline — featured variant, English copy
Rule 1 — Three times the copy
The steps:
- Count the characters in the original string, including spaces.
- Replace the string with capital W’s: one per character.
- Triple the count.
- Add two more W’s.
- Redesign anything that now breaks.
| Step | Layer | Working |
|---|---|---|
| 1. Count | Title "Sample featured case study" | 26 characters incl. spaces |
| 2. W’s | Title | one W per character |
| 3. Triple | Title | 78 W’s |
| 4. +2 | Title | (3 × 26) + 2 = 80 W’s |
| 1. Count | Description | 86 characters incl. spaces |
| 4. +2 | Description | (3 × 86) + 2 = 260 W’s |
| 1. Count | Tag "Design systems" | 14 characters |
| 4. +2 | Tag | 44 W’s |
| 1. Count | Tag "Strategy" | 8 characters |
| 4. +2 | Tag | 26 W’s |
Step 5 — drop the W-strings back into the same component:
Step 5. Same component, tripled copy
The decisions surface immediately. Does the title clamp at two lines with an ellipsis, or does the card grow vertically? The tag list wraps onto multiple rows — does it cap at a max row count and show +N more? The description pushes the cover plate out of vertical rhythm — is that acceptable, or does the description need a clamp?
Rule 2 — Three times the functions
The steps:
- Count every action, button and link inside the component.
- Triple the count.
- Decide how the component handles the overflow.
The card is currently a single <a> wrapping the whole block.
| Step | Action | Working |
|---|---|---|
| 1. Count | Whole-card link | 1 action |
| 2. Triple | — | 3 actions |
| 3. Redesign | ”Open”, “Save”, “Share” | Adding a button inside <a> creates a nested interactive — invalid HTML and broken keyboard/AT semantics |
Step 3 forces a structural decision in calm conditions rather than under deadline pressure: the card is either a link, or it hosts inline actions — not both. A title-as-link with an action row below is the usual answer.
Rule 3 — Three times the content
The steps:
- Count every content slot — images, tags, paragraphs, icons, stats, repeating children.
- Triple each count.
- Redesign with wrap rules, caps, or “view more” affordances. Some slots should triple gracefully; others should be capped.
Step 1. Baseline — featured variant with one cover, one description, two tags, four stats
| Step | Slot | Working |
|---|---|---|
| 1. Count | Cover plate / image | 1 |
| 2. Triple | Cover plate / image | 3 — but the card has one hero slot; cap at 1 |
| 1. Count | Description | 1 |
| 2. Triple | Description | 3 — clamp at 3 lines or accept the height |
| 1. Count | Tags | 2 |
| 2. Triple | Tags | 6 — wrap, or +N more chip |
| 1. Count | Stats | 4 |
| 2. Triple | Stats | 12 — wrap to multiple rows, or cap at 4 |
Step 3 — push the multiplied content back into the same component:
The image slot proves the point about caps: a second hero would hurt scannability, so the output is a contract — one image, that’s it — not a redesign. The tag list and stats grid each need an explicit overflow strategy. The tripled description breaks vertical rhythm.
Worked example B — DisplayControls
DisplayControls is the segmented control used in the homepage Display Settings panel and the theme drawer. Two fieldsets: Contrast (4 options) and Colour mode (3 options), plus an aria-live line reporting the active state.
Baseline — panel variant
Rule 1 — Three times the copy
The component’s options are hardcoded, so the demos below render the same markup with tripled labels rather than mutating the component itself. The CSS is unchanged — the layout breakage is real.
| Step | Layer | Working |
|---|---|---|
| 1. Count | "Low" | 3 |
| 4. +2 | "Low" | 11 W’s |
| 1. Count | "High -beta" | 10 |
| 4. +2 | "High -beta" | 32 W’s |
| 1. Count | "Decorative - beta" | 17 |
| 4. +2 | "Decorative - beta" | 53 W’s |
| 1. Count | "System" | 6 |
| 4. +2 | "System" | 20 W’s |
| 1. Count | Live region "Currently: low" | 14 |
| 4. +2 | Live region | 44 W’s |
Step 5 — push the W-strings into the markup:
Step 5. Same markup, tripled labels
The questions surface before you touch the code. Does the chip row scroll, wrap, or push overflow into a “More” menu? Does the live-region line clip, wrap, or sit inline next to the legend rather than beneath it?
Rule 2 — Three times the functions
Each option in a segmented group is one action. Contrast has 4, Colour mode has 3 — 7 actions in total.
| Step | Group | Working |
|---|---|---|
| 1. Count | Contrast | 4 options |
| 1. Count | Colour mode | 3 options |
| 1. Count | Total | 7 options |
| 2. Triple | Contrast | 12 options |
| 2. Triple | Colour mode | 9 options |
| 3. Redesign | Threshold | At what option count does the row stop being segmented and become a dropdown or a “More” menu? |
Step 3 — render the same markup with tripled option counts and watch the segmented row break:
Step 3. Same markup, tripled options (12 + 9)
The decision: should the threshold be per-variant (panel collapses earlier than drawer), or a single rule the component enforces? Tripling forces an explicit answer up front, so when someone wants to add a fifth contrast mode the component already knows what to do.
Rule 3 — Three times the content
The “content” for DisplayControls is the fieldset count. Two today; tripling implies six.
| Step | Slot | Working |
|---|---|---|
| 1. Count | Fieldsets | 2 (Contrast, Colour mode) |
| 2. Triple | Fieldsets | 6 — plausible additions: Motion, Density, Text size, Language |
| 3. Redesign | panel | Horizontal row has nowhere to put four more groups — cap at 2 + “More settings…” link, or stop being a panel above the threshold |
| 3. Redesign | drawer | Add scroll, or section dividers with headings |
Step 3 — render the same markup with six fieldsets:
Step 3. Same markup, six fieldsets (drawer variant)
In drawer the column simply gets longer — manageable with a scroll region or section headings. In panel (horizontal) six fieldsets is unworkable, so the redesign is structural: cap the panel and link out to a fuller settings surface.
When to set limits
Not every slot should triple gracefully. Some have a usability ceiling — a card with five hero images scans worse than a card with one. The output of the content rule is sometimes a cap: an explicit “this slot accepts at most N” rule, written into the component’s documentation. A cap is a valid result, not a failure of the exercise.
What you get
A component designed with the Rule of 3 supports:
- Responsiveness across viewport sizes, devices and browser zoom
- Multiple languages, where copy lengths vary
- Flexibility for additional use cases, supporting more functions and controls over time
On the first system I introduced this to, component lifespans between breaking revisions grew noticeably, and consuming teams stopped waiting on translated copy to find layout issues. The cost is one afternoon per component up-front. The payoff is months of avoided refactors and a system that holds its shape as teams add use cases.
Get the skill
The Rule of 3 is also packaged as a Claude skill that runs the exercise live in Figma. It checks the connection, walks you through which variants to test, then builds three Sections in the file (Copy, Functions, Content) populated with stressed instances. The skill writes nothing outside those three Sections, so cleanup is one selection and a delete.
To install: unzip into your local Claude skills directory (e.g. ~/.claude/skills/). Open Figma, connect the figma-console-local plugin, and ask Claude to “run rule of 3 on this component”.