Skip to content

Web Details & Guidelines #48

@JohnPhamous

Description

@JohnPhamous

Interactions

  • Match visual and hit targets
    • Exception: The visual target is small (less then 32px). Hit target should be at least 32px.
  • All flows work via keyboard
  • Every focusable element has a focus ring
  • Add aria-label when needed. Check the accessibility tree. This is important for humans/agents/llms/ai/everyone.
  • <Input>s font size needs to be at least 16px for mobile. This prevents iOS Safari from zooming/panning the page when an input is focused.
  • Buttons with loading states should show a loading indicator and the original label
  • Prefer to persist application state to the URL. This makes sharing, linking, refreshing, backwards/forward navigation just work.
  • Optimistic updates when possible
  • Menu options that require additional user input should end with ellipsis to signify that
  • Focus is managed correctly
  • Destructive operations have a confirmation

Animations

  • Have a prefers-reduced-motion variant
  • Prefer implementing with CSS, avoid main thread animations
    • Preference stack
      • CSS
      • Web Animations API
      • motion
  • Prioritize GPU-accelerated animations, doesn’t cause reflows/repaints
  • Be critical on whether an animation/transition is needed
  • Easing curves depend on the thing that’s animating

Layout

  • Optically aligned depending on the lockup. ±1px is ok.
  • Contrast sometimes need to be balanced too depending on the lockup
  • Everything should be aligned with something else on the page
  • Make sure it works on different screen sizes (mobile, laptop, ultra-wide)
    • Testing ultra-wide: Zoom out to 50%

Content

  • Use <Tooltip> only as a last resort prefering inline descriptions
  • Buttons with only icons need an aria-label
  • Skeletons mirror final content closely to prevent cumulative layout shift
  • Page <title> reflects current context
  • No dead ends. Each screen should have a next step.
  • Design and implement for empty, sparse, dense, and error states
  • Prefer left/right quotes
  • Limit text widows/orphans

Performance

Make sure to disable extensions and the Vercel Toolbar when testing performance. Extensions might add noise. The Vercel Toolbar has a known issue of adding forced reflow overhead.

  • Test on iOS low power mode and on MacOS Safari
  • Inspect rerenders (React DevTools or React Scan)
  • Profile with throttled CPU
  • Test with throttled network
  • Minimize reflows/repaints
  • POST/PATCH/DELETE complete in under 500ms

Forms

  • Enter submits when an input is focused
  • In <textarea> ⌘/Ctrl+Enter submits, Enter adds newline
  • Links should be <a>. ⌘/Ctrl+Click, middle click, right click → open a new tab, link affordances should work
  • Every control has a <label>, clicking it focuses the control
  • Clicking a <label> should make the associated control active
  • Keep submit enabled until submission starts; then disable during in-flight + show spinner + idempotency key. (Prevents double-submit while preserving the “let me try” principle.)
  • Submit buttons should never be disabled. Let the user submit an incomplete form as a feedback mechanism.
  • Checkboxes/radios should not have dead zones
  • Errors should appear as close to the originating thing as possible. For example input validation errors should be next to the input that’s causing the error, not at the top or bottom of the form.
  • <input>s should set autocomplete when possible. This makes it easier for people to fill out forms.
  • Some <input>s should disable spellcheck
  • <input>s should have the correct type and inputmode
  • Form field placeholders should end with an ellipsis as an additional signifier that the input has no value

Metrics

  • Business metrics are measured and are accurate

Copywriting

  • Headings & buttons: Title Case.
  • Keep it clear and concise, use as few words as possible
  • Action-oriented language
    • Instead of "You will need the CLI…" say "Install the CLI…"
  • Use consistent nouns and introduce as few nouns as possible
  • Use numerals for numbers
    • “8 deployments” instead of “eight deployments”
  • Use tabular-nums or Geist Mono when it’s important to compare numbers
  • Default to positive language
    • Frame messages in an encouraging, problem-solving way, even for errors.
    • Example: Instead of "Your deployment failed," say "Something went wrong—try again or contact support."
  • Error messages should guide users how to exit error state
    • Don’t just state what went wrong—tell them how to fix it.
    • Example: Instead of "Invalid API key," say "Your API key is incorrect or expired. Generate a new key in your account settings." The copy and button/links help educate and give the user an action.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions