How to Make Interactive SVGs Keyboard Accessible
Interactive Scalable Vector Graphics (SVGs) enhance web design with dynamic visuals, but they often present significant usability barriers for keyboard-only users. This article outlines how to make interactive SVG components accessible by properly managing keyboard focus, assigning semantic roles and labels, styling visible focus indicators, and handling standard keyboard event listeners.
Use Semantic Wrappers or Manage Tabindex
By default, SVG elements such as <path>,
<circle>, or <g> are not focusable
by standard keyboard navigation. The simplest and most robust way to
make an interactive SVG accessible is to wrap it inside a native HTML
interactive element, such as a <button> or an
<a> tag.
If wrapping the SVG in native HTML is not feasible, you must add
tabindex="0" directly to the interactive SVG container or
child element. This includes the element in the natural keyboard tab
sequence:
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" tabindex="0" role="button" aria-label="Submit Form" />
</svg>Define Roles and Accessible Names
Keyboard users rely on screen readers and clear semantics to understand an element’s function. When creating custom interactive SVGs:
- Assign an ARIA Role: Use attributes like
role="button",role="link", orrole="switch"to define what the element does. - Provide an Accessible Name: Use
aria-labeldirectly on the focusable element, or include<title>and<desc>elements within the SVG linked viaaria-labelledby.
Provide Visible Focus Indicators
Browsers do not always render default focus rings correctly on SVG
child elements. To ensure keyboard users can track their location on the
page, define explicit CSS focus styles using the :focus or
:focus-visible pseudo-classes.
svg [tabindex="0"]:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
stroke: #005fcc;
}Avoid setting outline: none without providing a distinct
visual alternative, such as altering the SVG’s stroke,
fill, or filter properties upon focus.
Implement Keyboard Event Handlers
Native HTML buttons automatically trigger their action on both
Enter and Space key presses. Custom
interactive SVG elements using tabindex="0" do not provide
this behavior by default. You must attach JavaScript event listeners for
keydown to handle both keys manually:
const svgButton = document.querySelector('svg [role="button"]');
svgButton.addEventListener('keydown', (event) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault(); // Prevent default scrolling on Space
triggerAction();
}
});Hide Decorative Elements
Ensure that non-interactive SVGs or internal elements that do not
require user action are kept out of the tab sequence. Add
aria-hidden="true" and focusable="false" to
decorative SVGs so assistive technologies and older browsers ignore them
during keyboard navigation.