Accessibility

How VitNode UI stays usable for everyone - keyboard focus rings, roomy touch targets, WCAG contrast, screen reader text, live announcements and reduced motion, shown live.

Every interactive component sits on a Base UI primitive, so keyboard support, focus management and ARIA come built in. Your job is mostly not to break it. Try the demos with a keyboard or a screen reader.

Keyboard focus

Rings use :focus-visible, so they show up for keyboards and stay out of the way for mice. Text fields always get one, since you're about to type. Custom controls should borrow the same classes.

<div
  tabIndex={0}
  className="outline-none focus-visible:ring-3 focus-visible:ring-ring/50"
/>

Touch targets

Small controls keep their compact look but get an invisible ::after hit area of at least 44px. Checkbox, RadioGroupItem and Switch always have it; the smaller icon Button sizes and NumberField steppers add it on touch screens via pointer-coarse:.

Contrast

The ratio is computed from the live theme tokens, so flip dark mode and watch it change. muted-foreground passes AA on background and card in both themes. Filled primary with white text drops to about 3.8:1 in dark mode, so keep it for short button labels.

Screen reader text

Icons are decoration; words carry the meaning. Icon-only Button sizes require an aria-label at the type level, and sr-only adds context that sighted users get from the layout.

<Badge>
  {unread}
  <span className="sr-only"> unread</span>
</Badge>

Announcements

Changes that happen without a page load need to be said out loud. role="status" waits politely for a pause; role="alert" interrupts. Alert picks for you: warning and destructive are alerts, everything else is a status. FieldError is an alert, Spinner is a labelled status, and a loading Button renames itself to "Loading".

Motion and transparency

These are your device's settings right now. Components respect them with motion-reduce:, reduced-transparency: and pointer-coarse:, so nobody gets a spinning headache or a blurry dialog they asked not to have. More in Motion.

Semantic HTML

<header>…</header>
<nav aria-label="Main">…</nav>
<main>
  <h1>Settings</h1>
  <img alt="Your avatar" src={avatarUrl} />
  <img alt="" src="/divider.svg" />
</main>
  • Use header, nav, main and real headings in order. Screen reader users jump between them like chapters.
  • Every image needs alt. Use alt="" only when it is purely decorative.
  • A button does things, a link goes places. Never put onClick on a div.