Skip to content

content-resilience

Long names, missing images, huge numbers, translations, 0 to 10,000 items.

When your agent loads it

Design and verify interfaces against real content — long and short names, missing images and avatars, huge numbers, long unbroken strings and URLs, user-generated content, translated and RTL text, dates and currencies, and lists with 0, 1, many, or thousands of items. Produces a content contract (min/typical/max per field with overflow rules) and a stress-test fixture set. Use when building components that display user or API data (cards, tables, lists, headers, avatars, badges, navigation labels), when designs were made with placeholder text, or when layouts break in production. Triggers on "long text breaks layout", "truncate", "overflow", "ellipsis", "missing image", "i18n", "German text too long", "large numbers", "user generated content". Not for choosing type styles.

Group
Content
Produces
Content contract + fixtures
Length
169 lines
npx skills add aviralj02/interface-skills --skill content-resilience

Installs only this skill. Add -g to install globally.

View source

PurposeLink to this section

Mockups use "Jane Doe", a perfectly cropped photo, and three list items. Production has a 90-character company name, no photo, a count of 1,284,332, a title in German, and a URL with no spaces. This skill defines what content each component must survive and how it behaves at the extremes — before production discovers it.

When to UseLink to this section

  • Building any component that renders content you do not control
  • Converting a design made with ideal placeholder content
  • Supporting multiple languages or user-generated content
  • Bugs: overlapping text, blown-out cards, squashed buttons, horizontal scroll on mobile

Core PrinciplesLink to this section

  1. Design with a range, not a sample. Every field has a minimum, typical, and maximum. Know all three.
  2. Truncation hides information; only truncate what can be recovered. If users need the full value, it must be reachable (title, tooltip on focus, detail view, expand).
  3. Some content must never be truncated. Amounts, prices, dates, error messages, legal text, and identifiers users need to match.
  4. Layouts give way; content keeps its meaning. Containers wrap, grow, or scroll; they do not clip meaning or overlap.
  5. Absence is content too. Missing avatar, missing description, null value — each needs a defined rendering.
  6. Quantity changes layout. 0, 1, a few, many, and thousands are different designs.
  7. Format for the user's locale, not the developer's.

WorkflowLink to this section

1. Write the content contractLink to this section

For each component, list every piece of dynamic content.

FieldSourceMinTypicalMaxCan be empty?Overflow rule
Project nameuser1 char12–30100nowrap to 2 lines, then clamp; full name in title + detail page
Owner avataruser uploadimageyesinitials on colored background derived from id
Descriptionuser080–2005,000yesclamp 3 lines in card; "No description" in muted text only on detail page
Task countcomputed05–2001,000,000+nocompact ("1.2M") in badge; exact in tooltip/detail
Updatedsystemnorelative < 7 days ("3h ago"), absolute otherwise; exact timestamp on hover/focus
Tagsuser01–350yesshow first 3 + "+N"

Get real maxima from the database schema, API validation, or production data — not guesses. If there is no maximum, that is a finding: add one or design for unbounded.

2. Choose overflow behavior per fieldLink to this section

BehaviorUse forRules
WrapNames, titles, headings, messagesAllow overflow-wrap: anywhere for long unbroken strings
Clamp N linesDescriptions, previewsFull content must be reachable
Truncate endSingle-line labels in dense listsFull value in accessible name / tooltip
Truncate middleFile names, paths, hashes, emails where the end mattersreport-final-v…-2024.pdf
CompactLarge numbers in badges/chartsExact value accessible
ScrollCode, logs, wide tablesScroll within its own container, never the page
Fade / "Show more"Long user contentExpand in place; keep position
Never truncateMoney, dates, error text, legal, IDs to matchLet the layout adapt

3. Handle absence and failureLink to this section

ContentMissing / failed rendering
AvatarInitials or generic icon; stable color per user; same size as image
Hero / thumbnailNeutral placeholder with preserved aspect ratio; no broken-image icon
Optional textOmit the row, or show "—" in tables; don't show "null", "undefined", "N/A" inconsistently
NameFallback chain: display name → email → "Unnamed user"
NumbersDistinguish 0 from unknown ("—")
DatesDistinguish "never" from unknown

Reserve image space with aspect-ratio or width/height to avoid layout shift, and handle onerror.

4. Design for quantityLink to this section

For every list, grid, tag set, avatar stack, or menu:

CountQuestion
0Empty state (see interface-states)
1Does singular grammar and layout look intentional?
Few (2–5)Typical design
Many (20–100)Scrolling, grouping, "show more"?
Huge (1,000+)Pagination, virtualization, search, filters, server-side counts

5. Handle user-generated and unusual contentLink to this section

Include in fixtures:

  • Long unbroken strings: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, long URLs, email addresses
  • Emoji and combined emoji (👩🏽‍💻), including in names and initials
  • RTL text (Arabic, Hebrew) and mixed-direction strings
  • CJK text (no spaces for wrapping)
  • Accents and diacritics, including stacked combining marks
  • Leading/trailing whitespace, multiple spaces, line breaks in single-line fields
  • HTML/markdown-looking input (<b>, **bold**) — rendered as text unless intentionally supported
  • Very short values: one character, one emoji

6. Handle translation and localeLink to this section

  • Budget 30–40% text expansion for short UI strings (more for very short ones: "OK" → "Aceptar")
  • Buttons and tabs grow; do not fix their width
  • Use logical CSS properties (margin-inline-start) for RTL
  • Format numbers, currency, dates, and relative times with locale-aware APIs (Intl)
  • Do not build sentences by concatenation; word order changes

7. Build and run the stress fixturesLink to this section

Create a fixture set per component: minimum, typical, maximum, missing, unusual, and quantity cases. Render them together (story, test page, or visual regression) at the narrowest supported width.

ChecklistLink to this section

  • Content contract written with real min/typical/max
  • Every field has an overflow rule
  • Nothing that must not be truncated is truncated
  • Truncated values are recoverable (including for keyboard and screen reader users)
  • Long unbroken strings cannot overflow containers
  • Every image has a sized placeholder and a failure fallback
  • Missing values render consistently
  • 0 vs unknown is distinguishable
  • Lists designed for 0, 1, many, and huge
  • Numbers, dates, currency formatted per locale
  • Layout tested with ~40% longer strings and RTL
  • Fixtures render together at narrowest width

Common MistakesLink to this section

  • Flex children without min-width: 0, so a long name pushes the action button off screen.
  • Ellipsis on a price or amount.
  • Truncated text with no way to see the rest, or a tooltip only reachable by mouse.
  • Fixed-width buttons that clip translated labels.
  • Initials fallback that breaks on emoji or single-word names.
  • "1000000" rendered raw or "1.2M" with no way to see the exact value where precision matters.
  • Relative dates only ("2 months ago") in contexts where the exact date matters (invoices, audit logs).
  • Rendering 5,000 DOM rows because the design showed 8.

ExampleLink to this section

Component: notification item

Fixtures and expected behavior:

CaseContentExpected
Typical"Ana commented on Q3 plan"single line
Long actor"Maximilian Alexander von Hohenberg-Schwarzenbach commented…"wraps to 2 lines; timestamp stays right-aligned on its own line on narrow
Long objectobject name 100 charsobject name clamps with ellipsis after 2 lines; full name in link's accessible name
Unbroken"commented on AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"breaks anywhere, no horizontal overflow
No avataractor has no imageinitials "MA" on stable color
Emoji nameactor "🦊 Fox"initials use first grapheme "🦊"
Deleted actoractor null"A former member" + generic avatar
RTLobject name in Arabicisolated with <bdi>, punctuation not reordered
Many2,400 unreadbadge "99+", list virtualized, "Mark all as read"

Implementation NotesLink to this section

  • CSS: min-width: 0 on flex/grid children that contain text; overflow-wrap: anywhere for user content; line-clamp for multi-line truncation; text-overflow: ellipsis with white-space: nowrap and overflow: hidden for single line.
  • Wrap user-provided inline strings in <bdi> (or dir="auto") inside mixed-direction sentences.
  • Use Intl.NumberFormat with notation: "compact" and Intl.RelativeTimeFormat / Intl.DateTimeFormat.
  • Split graphemes with Intl.Segmenter for initials, not string[0].
  • Put fixtures in stories or a test harness so the extremes are reviewed visually on every change.

Output ExpectationsLink to this section

Produce:

  1. Content contract per component — Field | Source | Min | Typical | Max | Empty? | Overflow rule.
  2. Absence rules — rendering for each missing/failed content type.
  3. Quantity plan — 0 / 1 / many / huge behavior for each collection.
  4. Stress fixture set — concrete values, ready to paste into stories or tests.
  5. Findings — when reviewing, each break with the case that triggers it and the fix, with file/line.