Guides

Accessibility

Accessible names, keyboard support, focus, announcements and reduced motion

Every vccs chart has an accessible name, and every interactive chart works with the keyboard. This page lists what the charts do for you and what you still need to set.

Give each chart a name

Every chart takes title (the accessible name) and desc (a longer description):

<BarChart
  :data="data"
  :height="300"
  title="Monthly visitors"
  desc="Desktop and mobile visitors from January to June. Desktop peaks in February."
>
  …
</BarChart>

Without title, the chart uses a generic name such as "Bar chart", "Radial bar chart", "Treemap", "Status history" or "Activity calendar"; a ComposedChart is called "Chart". A generic name does not say what the data is, so set title on every chart that people must understand.

  • title becomes the aria-label of the focusable chart element.
  • desc is linked with aria-describedby. Use it for the main finding of the chart, or a short text version of the data.
  • Sparkline builds its name from the data ("Trend: 12 values from 3 to 9") and reads the active point. JourneySankey names itself by its sessions and steps.

The accessibility layer

Cartesian and polar charts (BarChart, LineChart, AreaChart, ComposedChart, ScatterChart, PieChart, RadarChart, RadialBarChart, FunnelChart) have an accessibility layer that is on by default (accessibility-layer is true). With it, the chart wrapper:

  • is in the tab order (tabindex="0"; change it with tab-index),
  • has role="application" (change it with role), so screen readers pass the arrow keys to the chart,
  • has the title as aria-label and desc through aria-describedby,
  • moves the tooltip with the keyboard and announces it (see below).

Set :accessibility-layer="false" for a chart that is only decoration, or when you build your own keyboard model. The chart is then not focusable, and the <svg> gets role="img" with the title as its name.

Keyboard

Focus the chart with Tab. The keys depend on the chart type.

ChartsKeys
Axis charts: Bar, Line, Area, Composed, Radar, RadialBarFocus shows the first category. ArrowRight and ArrowLeft move one category; on a reversed X axis the direction follows the axis. Enter hides or shows the tooltip
Item charts: Pie, Scatter, FunnelArrowRight or ArrowDown moves to the next item, ArrowLeft or ArrowUp to the previous one. Home and End jump to the first and last item. Escape clears the selection. The order is series by series, then data order
Treemap, Sankey, SunburstChartThe same keys as item charts. Enter emits node-click for the active node
Tracker, Heatmap, CohortChart, CalendarHeatmapThe cells form one list (role="listbox"). Focus starts on the latest cell. Arrow keys move within the grid and skip empty places, Home and End jump to the first and last cell, Enter emits cell-click, Escape clears
SparklineFocus starts on the latest point. ArrowLeft and ArrowRight move one point, Home and End jump to the first and last point, Escape clears
JourneySankeyArrow keys move within a step (up and down) and along the largest band (left and right). Enter or Space pins the journey through the focused node and emits node-click, Escape clears it
BarListA normal HTML list. Rows with a link or an action are native links or buttons

The keyboard drives the same selection as the pointer: the tooltip shows the item, the item is drawn in its active state, and v-model:active-index receives the update. See Events and v-model.

Brush and Legend

  • Each Brush handle is a slider (role="slider") in the tab order, named "Range start" and "Range end". ArrowLeft and ArrowRight move it by one row. aria-valuetext reads the category.
  • Each Legend entry is a native <button> named "Toggle name series", with aria-pressed set while the series is shown. Enter and Space work like a click, including v-model:hidden.

Announcements

A chart with a <Tooltip> has a polite live region. When the keyboard moves the selection, it reads the tooltip text, for example "Feb: Desktop 305, Mobile 200". It uses the same formatter as the tooltip. Pointer movement is never announced, so hovering does not flood a screen reader.

Put a <Tooltip> in every chart that people use with the keyboard; without it, nothing is announced. Under a controlled v-model:active-index, the chart announces only after you accept the keyboard's request.

Focus styling

Keyboard focus draws a 2 px outline with a 2 px offset in --v-charts-focus (default: the system Highlight color). Pointer clicks do not show the outline. While the outline shows, the wrapper has a data-focus-visible attribute.

.dashboard {
  --v-charts-focus: #f97316;
}

Check that the focus color has a contrast of at least 3:1 against the page background. See Theming for all tokens.

Reduced motion

Charts follow the operating system's reduce motion setting: data changes snap to their final state, and the tooltip stops gliding. You do not have to do anything. To stop motion for everybody, set :is-animation-active="false" on the chart. See Animation.

Style parts without colors only

Do not use color as the only way to tell series apart. Add a Legend, labels, different stroke-dasharray values or different symbols.

To style chart parts, use the data-slot attributes instead of generated class names or ids:

data-slotPart
chartThe chart wrapper (focusable element)
surfaceThe <svg>
plotThe plot area
gridCartesianGrid and PolarGrid
x-axis, y-axisCartesian axes
angle-axis, radius-axisPolar axes
seriesEach series layer
tooltip, legend, brushThose components
cellA cell of a cell chart
labelA Label

Native aria-* attributes that you put on a chart or a series are passed on to the element.

Checklist

  • Set title on every chart, and desc when the finding is not obvious.
  • Put a <Tooltip> in every interactive chart.
  • Keep the accessibility layer on, unless the chart is decoration.
  • Give the focus color enough contrast.
  • Do not rely on color alone.
Copyright © 2026