Distilled from Vercel's https://github.com/vercel-labs/web-interface-guidelines
Interactions
- [ ] Keyboard works everywhere (WAI-ARIA patterns)
- [ ] Clear focus rings (
:focus-visible) - [ ] Manage focus (traps, move, return)
- [ ] Match visual & hit targets (≥24px desktop, ≥44px mobile)
- [ ] Mobile input font ≥16px
- [ ] Never disable zoom
- [ ] Hydration-safe inputs
- [ ] Never block paste
- [ ] Loading buttons show indicator + original label
- [ ] Minimum loading duration (150-300ms delay, 300-500ms min)
- [ ] URL as state (shareable, refreshable)
- [ ] Optimistic updates with rollback
- [ ] Ellipsis for further input & loading states
- [ ] Confirm destructive actions
- [ ]
touch-action: manipulationon controls - [ ] Set
webkit-tap-highlight-color - [ ] Generous hit targets, predictable interactions
- [ ] Delay first tooltip, no delay for peers
- [ ]
overscroll-behavior: containin modals/drawers - [ ] Scroll positions persist on Back/Forward
- [ ] Autofocus single input on desktop (rarely mobile)
- [ ] No dead zones - interactive looks interactive
- [ ] Deep-link everything (filters, tabs, panels)
- [ ] Clean drag interactions (disable selection, use
inert) - [ ] Links are
<a>or<Link>(not buttons/divs) - [ ] Announce async updates (aria-live)
- [ ] Locale-aware keyboard shortcuts
Animations
- [ ] Honor
prefers-reduced-motion - [ ] Prefer CSS > Web Animations API > JS libraries
- [ ] GPU-accelerated properties (
transform,opacity) - [ ] Animate only for clarity or delight
- [ ] Easing fits the subject
- [ ] Interruptible by user input
- [ ] Input-driven, not autoplay
- [ ] Correct transform origin
- [ ] Never
transition: all(explicit properties only) - [ ] SVG transforms on
<g>wrappers withtransform-box: fill-box
Layout
- [ ] Optical alignment (±1px adjustments)
- [ ] Deliberate alignment (grid, baseline, edge, center)
- [ ] Balance contrast in text/icon lockups
- [ ] Test mobile, laptop, ultra-wide
- [ ] Respect safe areas (notches, insets)
- [ ] No excessive scrollbars
- [ ] Let browser size things (flex/grid over JS)
Content
- [ ] Inline help first, tooltips last
- [ ] Stable skeletons mirror final content
- [ ] Accurate
<title>reflects context - [ ] No dead ends (next step or recovery)
- [ ] Design all states (empty, sparse, dense, error)
- [ ] Curly quotes (" ")
- [ ] Avoid widows/orphans
- [ ] Tabular numbers for comparisons
- [ ] Redundant status cues (not color alone)
- [ ] Icons have text labels
- [ ] Accessible names exist even if labels hidden
- [ ] Use ellipsis character
…not... - [ ]
scroll-margin-topon headings - [ ] Handle short, average, long content
- [ ] Locale-aware formats (dates, numbers, currency)
- [ ] Language via
Accept-Language, not IP/GPS - [ ] Accurate
aria-label,aria-hidden - [ ] Icon-only buttons have
aria-label - [ ] Semantics before ARIA (native elements first)
- [ ] Hierarchical
<h1–h6>+ skip link - [ ] Brand resources from logo right-click
- [ ] Non-breaking spaces for glued terms (
,⁠)
Forms
- [ ] Enter submits (single input or last control)
- [ ] Textarea: ⌘/⌃+Enter submits, Enter = new line
- [ ] Every control has
<label>or association - [ ] Label clicks focus control
- [ ] Submit enabled until in-flight (spinner + idempotency key)
- [ ] Don't block typing (validate, don't restrict)
- [ ] Don't pre-disable submit (surface validation)
- [ ] No dead zones on checkboxes/radios
- [ ] Errors next to fields, focus first error on submit
- [ ] Set
autocomplete& meaningfulname - [ ] Disable spellcheck for emails, codes, usernames
- [ ] Correct
type&inputmode - [ ] Placeholders end with ellipsis, show example
- [ ] Warn before navigation with unsaved changes
- [ ] Password manager & 2FA compatible
- [ ] Don't trigger password managers for non-auth
- [ ] Trim trailing whitespace from input
- [ ] Set
background-color&coloron<select>
Performance
- [ ] Test iOS Low Power Mode & macOS Safari
- [ ] Disable extensions when profiling
- [ ] Track re-renders (React DevTools, React Scan)
- [ ] Throttle CPU/network when profiling
- [ ] Minimize layout work (batch reads/writes)
- [ ] POST/PATCH/DELETE <500ms
- [ ] Prefer uncontrolled inputs, cheap controlled loops
- [ ] Virtualize large lists
- [ ] Preload above-fold images, lazy-load rest
- [ ] Set explicit image dimensions (no CLS)
- [ ]
<link rel="preconnect">for asset/CDN domains - [ ] Preload critical fonts
- [ ] Subset fonts (unicode-range)
- [ ] Expensive work in Web Workers
Design
- [ ] Layered shadows (ambient + direct)
- [ ] Crisp borders + shadows
- [ ] Nested radii (child ≤ parent, concentric)
- [ ] Hue consistency on non-neutral backgrounds
- [ ] Color-blind-friendly chart palettes
- [ ] Prefer APCA over WCAG 2 for contrast
- [ ] Interactions increase contrast
- [ ] Set
<meta name="theme-color"> - [ ] Set
color-scheme: darkon<html>for dark themes - [ ] Animate wrapper, not text node (or
translateZ(0)) - [ ] Avoid gradient banding (use background images)
Copywriting (Vercel-specific)
- [ ] Active voice
- [ ] Headings/buttons: Title Case (Chicago)
- [ ] Marketing pages: sentence case
- [ ] Clear & concise
- [ ] Prefer
&overand - [ ] Action-oriented language
- [ ] Keep nouns consistent
- [ ] Second person, no first person
- [ ] Consistent placeholders (
YOUR_API_TOKEN_HERE,0123456789) - [ ] Numerals for counts
- [ ] Consistent currency (0 or 2 decimals, never mix)
- [ ] Space between numbers & units (
10 MB, use ) - [ ] Default to positive language
- [ ] Error messages guide the exit
- [ ] Avoid ambiguity (specific labels)
👋 About the Author
If you made it this far, you probably care about shipping fast without breaking things.
I build AI x Crypto MVPs for startups who need to go from idea to working product in weeks, not months.
What I do:
🤖 AI agents & chatbot interfaces (yes, including the one you could be using right now)
⛓️ Crypto integrations (EVM, Solana, L2s, Privy, smart contracts)
🛠️ DevTools & NPM packages that actually solve problems
🚀 SEO-optimized web apps that rank
Currently: Building open-source tools and taking on select freelance projects.
Let's talk:
🐦 Twitter: @SivaramPg
📦 GitHub: github.com/SivaramPg
🌐 Portfolio: sivaramp.com
📧 Email: [dev.sivaramp@gmail.com]
P.S. If you're building something weird in AI or crypto and want to bounce ideas, my DMs are open. No pitch, just nerding out.
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.