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:

  1. Assign an ARIA Role: Use attributes like role="button", role="link", or role="switch" to define what the element does.
  2. Provide an Accessible Name: Use aria-label directly on the focusable element, or include <title> and <desc> elements within the SVG linked via aria-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.