Accessibility

UIBlox is built with accessibility as a core principle, not an afterthought. Every component is designed to be WCAG 2.1 AA compliant, ensuring your applications work for everyone—regardless of how they interact with technology.

Our Accessibility Vision

We believe the web should be usable by everyone. Accessibility isn't just about compliance—it's about creating inclusive experiences that respect all users. When you build with UIBlox, you're building for the 1 billion+ people worldwide who have disabilities, the aging population, users with temporary impairments, and everyone who benefits from clear, well-structured interfaces.

100%
Keyboard navigable
WCAG 2.1
AA Compliant
ARIA
Built-in support
Screen Reader
Tested & optimized

Keyboard Navigation

All UIBlox components are fully keyboard accessible. Users who rely on keyboards, switch devices, or other assistive technologies can navigate and interact with every component.

KeyAction
TabMove focus to next interactive element
Shift + TabMove focus to previous interactive element
Enter / SpaceActivate buttons, links, and controls
EscapeClose modals, dropdowns, and overlays
Arrow KeysNavigate within tabs, menus, and select options
Home / EndJump to first/last item in lists
// Example: Focus-visible styling in UIBlox components
// All interactive elements have clear focus indicators

<Button>
  Click me
</Button>
// Focus ring appears on keyboard navigation (Tab)
// but not on mouse click (focus-visible behavior)

// CSS applied automatically:
// focus-visible:outline-none
// focus-visible:ring-2
// focus-visible:ring-[#3d9fdf]
// focus-visible:ring-offset-2

ARIA Attributes

UIBlox components include appropriate ARIA attributes automatically. Here's how to enhance accessibility further in your implementations.

Labeling Elements

// Always label form inputs - UIBlox Input supports this natively
<div>
  <label htmlFor="email" className="block text-sm font-medium text-white mb-2">
    Email address
  </label>
  <Input
    id="email"
    type="email"
    placeholder="you@example.com"
    aria-describedby="email-hint"
  />
  <p id="email-hint" className="mt-1 text-sm text-[#94a3b8]">
    We'll never share your email.
  </p>
</div>

// For icon-only buttons, use aria-label
<Button size="icon" aria-label="Close dialog">
  <XIcon className="h-4 w-4" />
</Button>

// For buttons with loading states
<Button disabled aria-busy="true">
  <Spinner className="mr-2" aria-hidden="true" />
  Saving...
</Button>

Live Regions for Dynamic Content

// Announce status updates to screen readers
<Alert
  variant="success"
  role="status"
  aria-live="polite"
>
  <AlertTitle>Changes saved</AlertTitle>
  <AlertDescription>Your profile has been updated.</AlertDescription>
</Alert>

// For urgent notifications
<Alert
  variant="destructive"
  role="alert"
  aria-live="assertive"
>
  <AlertTitle>Error</AlertTitle>
  <AlertDescription>Failed to save changes. Please try again.</AlertDescription>
</Alert>

// Toast notifications (auto-dismissed)
<div role="status" aria-live="polite" aria-atomic="true">
  {toastMessage}
</div>

Modal Dialogs

// UIBlox Modal includes these automatically
<Modal
  open={isOpen}
  onClose={() => setIsOpen(false)}
  // Built-in: role="dialog", aria-modal="true"
>
  <ModalHeader>
    <ModalTitle>Confirm Action</ModalTitle>
    <ModalDescription>
      Are you sure you want to delete this item?
    </ModalDescription>
  </ModalHeader>
  <ModalContent>
    {/* Content here */}
  </ModalContent>
  <ModalFooter>
    <Button variant="outline" onClick={() => setIsOpen(false)}>
      Cancel
    </Button>
    <Button variant="destructive">
      Delete
    </Button>
  </ModalFooter>
</Modal>

// Focus is automatically trapped inside the modal
// Escape key closes the modal
// Focus returns to trigger element on close

Color & Contrast

UIBlox maintains WCAG 2.1 AA color contrast ratios throughout. Our blueprint theme is designed with accessibility in mind.

Contrast Requirements

  • 4.5:1 minimum for normal text
  • 3:1 minimum for large text (18px+ or 14px bold)
  • 3:1 minimum for UI components and graphics

Don't Rely on Color Alone

  • Use icons alongside color for status
  • Add text labels for error/success states
  • Use patterns or shapes when needed
// Good: Icon + color + text for error state
<div className="flex items-center gap-2 text-red-400">
  <AlertCircleIcon className="h-4 w-4" aria-hidden="true" />
  <span>Please enter a valid email address</span>
</div>

// Good: Success state with multiple indicators
<Alert variant="success">
  <CheckCircleIcon className="h-4 w-4" aria-hidden="true" />
  <AlertTitle>Success</AlertTitle>
  <AlertDescription>Your changes have been saved.</AlertDescription>
</Alert>

// Bad: Color only (avoid this)
<span className="text-red-500">Invalid input</span>

Accessible Forms

Form accessibility is critical. Every input needs proper labeling, error states must be announced, and validation should be clear.

// Complete accessible form example
function ContactForm() {
  const [errors, setErrors] = useState({});

  return (
    <form aria-label="Contact form" noValidate>
      {/* Input with label and description */}
      <div className="space-y-2">
        <label htmlFor="name" className="text-sm font-medium text-white">
          Full name <span className="text-red-400" aria-hidden="true">*</span>
          <span className="sr-only">(required)</span>
        </label>
        <Input
          id="name"
          type="text"
          required
          aria-required="true"
          aria-invalid={errors.name ? "true" : "false"}
          aria-describedby={errors.name ? "name-error" : undefined}
        />
        {errors.name && (
          <p id="name-error" className="text-sm text-red-400" role="alert">
            {errors.name}
          </p>
        )}
      </div>

      {/* Checkbox with proper labeling */}
      <div className="flex items-center gap-2">
        <Checkbox
          id="terms"
          aria-describedby="terms-description"
        />
        <label htmlFor="terms" className="text-sm text-[#e2e8f0]">
          I agree to the terms and conditions
        </label>
      </div>
      <p id="terms-description" className="sr-only">
        By checking this box, you agree to our terms of service and privacy policy.
      </p>

      {/* Select with proper labeling */}
      <div className="space-y-2">
        <label htmlFor="country" className="text-sm font-medium text-white">
          Country
        </label>
        <Select
          id="country"
          options={countries}
          placeholder="Select your country"
          aria-required="true"
        />
      </div>

      {/* Submit with loading state */}
      <Button
        type="submit"
        disabled={isSubmitting}
        aria-busy={isSubmitting}
      >
        {isSubmitting ? "Submitting..." : "Submit"}
      </Button>
    </form>
  );
}

Form Accessibility Checklist

  • • Every input has a visible <label> or aria-label
  • • Required fields are marked with aria-required="true"
  • • Error messages use role="alert" or aria-live
  • • Invalid inputs have aria-invalid="true"
  • • Error messages are linked with aria-describedby
  • • Submit buttons indicate loading state with aria-busy

Screen Reader Support

UIBlox components are tested with major screen readers. Here's how to ensure your implementation works well.

Testing Tools

  • VoiceOver - Built into macOS/iOS
  • NVDA - Free, Windows
  • JAWS - Industry standard, Windows
  • TalkBack - Built into Android

Browser Extensions

  • axe DevTools - Automated testing
  • WAVE - Visual feedback
  • Lighthouse - Built into Chrome
  • Accessibility Insights - Microsoft
// Screen reader utilities in UIBlox

// Visually hidden but announced by screen readers
<span className="sr-only">
  Opens in a new window
</span>

// Hide decorative elements from screen readers
<svg aria-hidden="true" className="h-4 w-4">
  {/* decorative icon */}
</svg>

// Announce dynamic content
<div aria-live="polite" aria-atomic="true">
  {statusMessage}
</div>

// Skip link for keyboard users (add to your layout)
<a
  href="#main-content"
  className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4
             focus:z-50 focus:px-4 focus:py-2 focus:bg-[#1a73b5] focus:text-white
             focus:rounded-lg"
>
  Skip to main content
</a>

Component Accessibility Reference

Quick reference for accessibility features in each UIBlox component.

ComponentKeyboardARIAFocus
ButtonEnter, Spacearia-disabled, aria-busy
InputStandardaria-invalid, aria-describedby
CheckboxSpacearia-checked
SwitchEnter, Spacerole=switch, aria-checked
SelectArrows, Enter, Escapearia-expanded, aria-selected
ModalEscape, Tab traprole=dialog, aria-modal
DropdownArrows, Enter, Escapearia-expanded, aria-haspopup
TabsArrows, Home, Endrole=tablist/tab/tabpanel
TooltipFocus/Escaperole=tooltip
Alertrole=alert, aria-liveN/A

Learn More

Dive deeper into web accessibility with these resources.

Ready to Build Accessible Interfaces?

Explore our components—each one documents its accessibility features and best practices.