Skip to main content
You are viewing Pre-Alpha documentation.
Vuetify0 Logo

Accessibility

v0 provides ARIA attributes out-of-the-box through the attrs pattern. You provide styling and visual feedback.

Edit this page
Report a Bug
Copy Page as Markdown
IntermediateJan 11, 2026

The attrs Pattern

Every v0 component exposes an attrs object containing all accessibility attributes. Spread it onto your elements:

vue
<script setup>
  import { Selection } from '@vuetify/v0'

  const items = ['Apple', 'Banana', 'Cherry']
</script>

<template>
  <Selection.Root v-slot="{ attrs }">
    <div v-bind="attrs">
      <Selection.Item v-for="item in items" :key="item" v-slot="{ attrs }">
        <button v-bind="attrs">{{ item }}</button>
      </Selection.Item>
    </div>
  </Selection.Root>
</template>

What’s Included in attrs

ComponentARIA Attributes Provided
Selection.Itemaria-selected, aria-disabled, data-selected, data-disabled
Group.Itemrole="checkbox", aria-checked, aria-disabled, data-selected, data-disabled, data-mixed
ExpansionPanel.Activatorid, role, tabindex, aria-expanded, aria-controls, aria-disabled
Pagination.Rootaria-label, role="navigation" (when not using <nav>)
Popover.Activatorpopovertarget, data-popover-open (uses native popover API)
Tip

Always spread the attrs object from slot props onto your interactive elements. Missing ARIA attributes break screen reader support.

Developer Responsibilities

v0 provides the ARIA plumbing. You must provide:

ResponsibilityExample
Visual focus indicators:focus-visible { outline: 2px solid blue }
Color contrastEnsure 4.5:1 ratio minimum
Visible labelsAdd <label> or aria-label for inputs
Skip linksNavigation landmarks for keyboard users

Focus Trapping

v0 does not provide focus trapping. Use external solutions:

Roving Tabindex

v0 does not provide roving tabindex. This keeps the library headless - implement in your design system layer if needed for arrow key navigation between items.

Keyboard Navigation

What v0 Handles

  • tabindex management (-1 when disabled, 0 when enabled)
  • ARIA state synchronization (aria-expanded, aria-selected)
  • Data attributes for styling (data-selected, data-disabled)

What You Implement

PatternKeys to Handle
List selectionArrow keys, Home/End
MenusArrow keys, Escape, Enter
DialogsEscape to close, focus trap
TabsArrow keys, Home/End
ts
// You implement navigation logic - v0 provides selection state
function onKeydown (e: KeyboardEvent, ids: string[], currentIndex: number) {
  switch (e.key) {
    case 'ArrowDown': selection.select(ids[currentIndex + 1]); break
    case 'ArrowUp': selection.select(ids[currentIndex - 1]); break
    case 'Home': selection.select(ids[0]); break
    case 'End': selection.select(ids[ids.length - 1]); break
  }
}

Testing Strategies

Automated Testing

MyComponent.test.ts
import { axe } from 'vitest-axe'

it('passes accessibility audit', async () => {
  const { container } = render(MyComponent)
  expect(await axe(container)).toHaveNoViolations()
})

Manual Testing Checklist

Use this checklist during manual QA:

markdown
- [ ] Tab through all interactive elements
- [ ] Verify focus visibility
- [ ] Test with keyboard only (no mouse)
- [ ] Check color contrast with DevTools
- [ ] Validate with browser accessibility tree
ToolPurpose
axe DevToolsBrowser extension for WCAG scanning
LighthouseBuilt-in Chrome audit
NVDA/VoiceOverScreen reader verification

Internationalization

v0’s useLocale handles RTL and translated labels. See useLocale for accessibility label translations.


© 2016-1970 Vuetify, LLC
Ctrl+/