Accessibility
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.
titlebecomes thearia-labelof the focusable chart element.descis linked witharia-describedby. Use it for the main finding of the chart, or a short text version of the data.Sparklinebuilds its name from the data ("Trend: 12 values from 3 to 9") and reads the active point.JourneySankeynames 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 withtab-index), - has
role="application"(change it withrole), so screen readers pass the arrow keys to the chart, - has the
titleasaria-labelanddescthrougharia-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.
| Charts | Keys |
|---|---|
| Axis charts: Bar, Line, Area, Composed, Radar, RadialBar | Focus 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, Funnel | ArrowRight 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, SunburstChart | The same keys as item charts. Enter emits node-click for the active node |
| Tracker, Heatmap, CohortChart, CalendarHeatmap | The 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 |
| Sparkline | Focus starts on the latest point. ArrowLeft and ArrowRight move one point, Home and End jump to the first and last point, Escape clears |
| JourneySankey | Arrow 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 |
| BarList | A 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".ArrowLeftandArrowRightmove it by one row.aria-valuetextreads the category. - Each Legend entry is a native
<button>named "Toggle name series", witharia-pressedset while the series is shown.EnterandSpacework like a click, includingv-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-slot | Part |
|---|---|
chart | The chart wrapper (focusable element) |
surface | The <svg> |
plot | The plot area |
grid | CartesianGrid and PolarGrid |
x-axis, y-axis | Cartesian axes |
angle-axis, radius-axis | Polar axes |
series | Each series layer |
tooltip, legend, brush | Those components |
cell | A cell of a cell chart |
label | A Label |
Native aria-* attributes that you put on a chart or a series are passed on to the element.
Checklist
- Set
titleon every chart, anddescwhen 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.
Related
- Events and v-model: selection, keyboard and control rules
- Theming:
--v-charts-focusand the other tokens - Animation: reduced motion and timing