Web Interface Guidelines
Checklist for reviewing UI code for compliance with comprehensive web interface, accessibility, performance, and content guidelines.
Views
151
Uses
14
Updated
February 3, 2026
| Property | Value |
|---|---|
| description | Review UI code for Vercel Web Interface Guidelines compliance |
| argument-hint | <file-or-pattern> |
| keywords | ux-design, ui-design, accessibility, performance, best-practices, documentation, css, components |
Web Interface Guidelines
Review these files for compliance: $ARGUMENTS
Read files, check against rules below. Output concise but comprehensive—sacrifice grammar for brevity. High signal-to-noise.
Rules
Accessibility
- Icon-only buttons need
aria-label - Form controls need
<label>oraria-label - Interactive elements need keyboard handlers (
onKeyDown/onKeyUp) <button>for actions,<a>/<Link>for navigation (not<div onClick>)- Images need
alt(oralt=""if decorative) - Decorative icons need
aria-hidden="true" - Async updates (toasts, validation) need
aria-live="polite" - Use semantic HTML (
<button>,<a>,<label>,<table>) before ARIA - Headings hierarchical
<h1>–<h6>; include skip link for main content scroll-margin-topon heading anchors
Focus States
- Interactive elements need visible focus:
focus-visible:ring-*or equivalent - Never
outline-none/outline: nonewithout focus replacement - Use
:focus-visibleover:focus(avoid focus ring on click) - Group focus with
:focus-withinfor compound controls
Forms
- Inputs need
autocompleteand meaningfulname - Use correct
type(email,tel,url,number) andinputmode - Never block paste (
onPaste+preventDefault) - Labels clickable (
htmlForor wrapping control) - Disable spellcheck on emails, codes, usernames (
spellCheck={false}) - Checkboxes/radios: label + control share single hit target (no dead zones)
- Submit button stays enabled until request starts; spinner during request
- Errors inline next to fields; focus first error on submit
- Placeholders end with
…and show example pattern autocomplete="off"on non-auth fields to avoid password manager triggers- Warn before navigation with unsaved changes (
beforeunloador router guard)
Animation
- Honor
prefers-reduced-motion(provide reduced variant or disable) - Animate
transform/opacityonly (compositor-friendly) - Never
transition: all—list properties explicitly - Set correct
transform-origin - SVG: transforms on
<g>wrapper withtransform-box: fill-box; transform-origin: center - Animations interruptible—respond to user input mid-animation
Typography
…not...- Curly quotes
""not straight" - Non-breaking spaces:
10 MB,⌘ K, brand names - Loading states end with
…:"Loading…","Saving…" - for number columns/comparisons
font-variant-numeric: tabular-nums - Use
text-wrap: balanceortext-prettyon headings (prevents widows)
Content Handling
- Text containers handle long content:
truncate,line-clamp-*, orbreak-words - Flex children need
min-w-0to allow text truncation - Handle empty states—don't render broken UI for empty strings/arrays
- User-generated content: anticipate short, average, and very long inputs
Images
<img>needs explicitwidthandheight(prevents CLS)- Below-fold images:
loading="lazy" - Above-fold critical images:
priorityorfetchpriority="high"
Performance
- Large lists (>50 items): virtualize (
virtua,content-visibility: auto) - No layout reads in render (
getBoundingClientRect,offsetHeight,offsetWidth,scrollTop) - Batch DOM reads/writes; avoid interleaving
- Prefer uncontrolled inputs; controlled inputs must be cheap per keystroke
- Add
<link rel="preconnect">for CDN/asset domains - Critical fonts:
<link rel="preload" as="font">withfont-display: swap
Navigation & State
- URL reflects state—filters, tabs, pagination, expanded panels in query params
- Links use
<a>/<Link>(Cmd/Ctrl+click, middle-click support) - Deep-link all stateful UI (if uses
useState, consider URL sync via nuqs or similar) - Destructive actions need confirmation modal or undo window—never immediate
Touch & Interaction
touch-action: manipulation(prevents double-tap zoom delay)-webkit-tap-highlight-colorset intentionallyoverscroll-behavior: containin modals/drawers/sheets- During drag: disable text selection,
inerton dragged elements autoFocussparingly—desktop only, single primary input; avoid on mobile
Safe Areas & Layout
- Full-bleed layouts need
env(safe-area-inset-*)for notches - Avoid unwanted scrollbars:
overflow-x-hiddenon containers, fix content overflow - Flex/grid over JS measurement for layout
Dark Mode & Theming
color-scheme: darkon<html>for dark themes (fixes scrollbar, inputs)<meta name="theme-color">matches page background- Native
<select>: explicitbackground-colorandcolor(Windows dark mode)
Locale & i18n
- Dates/times: use
Intl.DateTimeFormatnot hardcoded formats - Numbers/currency: use
Intl.NumberFormatnot hardcoded formats - Detect language via
Accept-Language/navigator.languages, not IP
Hydration Safety
- Inputs with
valueneedonChange(or usedefaultValuefor uncontrolled) - Date/time rendering: guard against hydration mismatch (server vs client)
suppressHydrationWarningonly where truly needed
Hover & Interactive States
- Buttons/links need
hover:state (visual feedback) - Interactive states increase contrast: hover/active/focus more prominent than rest
Content & Copy
- Active voice: "Install the CLI" not "The CLI will be installed"
- Title Case for headings/buttons (Chicago style)
- Numerals for counts: "8 deployments" not "eight"
- Specific button labels: "Save API Key" not "Continue"
- Error messages include fix/next step, not just problem
- Second person; avoid first person
&over "and" where space-constrained
Anti-patterns (flag these)
user-scalable=noormaximum-scale=1disabling zoomonPastewithpreventDefaulttransition: alloutline-nonewithout focus-visible replacement- Inline
onClicknavigation without<a> <div>or<span>with click handlers (should be<button>)- Images without dimensions
- Large arrays
.map()without virtualization - Form inputs without labels
- Icon buttons without
aria-label - Hardcoded date/number formats (use
Intl.*) autoFocuswithout clear justification
Output Format
Group by file. Use file:line format (VS Code clickable). Terse findings.
## src/Button.tsx
src/Button.tsx:42 - icon button missing aria-label
src/Button.tsx:18 - input lacks label
src/Button.tsx:55 - animation missing prefers-reduced-motion
src/Button.tsx:67 - transition: all → list properties
## src/Modal.tsx
src/Modal.tsx:12 - missing overscroll-behavior: contain
src/Modal.tsx:34 - "..." → "…"
## src/Card.tsx
✓ passState issue + location. Skip explanation unless fix non-obvious. No preamble.
