Clean Markup

Writing Accessible Inline SVG Icons with Semantic ARIA Attributes

Writing Accessible Inline SVG Icons with Semantic ARIA Attributes

Inline Scalable Vector Graphics (SVG) are the gold standard for crisp icons and design system assets on the modern web. However, without deliberate accessibility markup, screen readers can interpret SVGs inconsistently—either ignoring interactive icon buttons altogether or announcing confusing internal geometry numbers and element names.

Building an accessible SVG strategy requires distinguishing between decorative graphics that should be silenced and standalone informative icons that convey critical user actions.

Example

Consider a common user interface pattern: an icon-only dismiss button and an informative status icon with text:

<!-- Pattern 1: Standalone icon button requiring an accessible name -->
<button type="button" class="btn-close" aria-label="Close dialog">
  <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
    <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
  </svg>
</button>

<!-- Pattern 2: Standalone informative graphic without accompanying text -->
<svg viewBox="0 0 24 24" role="img" aria-labelledby="status-title" focusable="false">
  <title id="status-title">System operational: all services normal</title>
  <circle cx="12" cy="12" r="10" fill="#04ae92" />
</svg>

Implementation

To prevent older versions of Internet Explorer from making SVGs tab-focusable, always append focusable="false". For decorative icons accompanying visible labels, hide the SVG explicitly with aria-hidden="true":

.btn-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  border: 1px solid var(--lightgray);
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
}

.btn-close svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

Main Point: Use aria-hidden="true" on decorative inline icons, and give icon-only controls explicit names with aria-label or <title> connected via aria-labelledby.

Credits

Photo by Jeremy Bishop on Unsplash

← Home