DEV Community

Jan
Jan

Posted on

4 Ways to Include SVG in HTML and a11y consideration

Here are 4 common approaches for including SVGs in HTML, along with a sample examples, comparison tables and accessibility considerations:

1. Using <object>

<object type="image/svg+xml" data="icon.svg"></object>
Enter fullscreen mode Exit fullscreen mode

2. Inline SVG

<svg width="100" height="100" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="skyblue" />
</svg>
Enter fullscreen mode Exit fullscreen mode

3. SVG as a Background Image (CSS)

<div class="icon"></div>

<style>
  .icon {
    width: 100px;
    height: 100px;
    background-image: url('icon.svg');
    background-size: cover;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

4. SVG as an <img>

<img src="icon.svg" alt="Icon" width="100" height="100">
Enter fullscreen mode Exit fullscreen mode

Comparison Table

Method Advantages Disadvantages
<object> - Loads external SVG
- Supports fallback
- Separate from DOM
- No direct CSS/JS access to inner elements
- More HTTP requests
Inline SVG - Full control via CSS & JS
- Animatable
- Accessible in DOM
- Clutters HTML
- Can't reuse easily without duplication
Background Image - Clean HTML
- Good for decorative use
- CSS control on container
- No control over SVG internals
- Not accessible or interactive
<img> - Simple & semantic
- Easy to use
- Can include alt text
- No CSS/JS access to inner elements
- Limited interactivity

SVG & Accessibility

✅ 1. <object> – Moderate Accessibility

<object type="image/svg+xml" data="icon.svg">Fallback text</object>
Enter fullscreen mode Exit fullscreen mode

Pros:

  • You can provide fallback text for screen readers and browsers that don’t support SVG.
  • External SVGs can contain their own <title>, <desc>, and ARIA attributes.

Cons:

  • Screen readers might not access the inner SVG content unless it’s well-structured inside the file.
  • Accessibility depends heavily on how the external SVG file is authored.

✅ 2. Inline SVG – Best Accessibility

<svg role="img" aria-labelledby="titleId descId">
  <title id="titleId">Blue circle</title>
  <desc id="descId">A simple circle shape filled with sky blue</desc>
  <circle cx="50" cy="50" r="40" fill="skyblue" />
</svg>
Enter fullscreen mode Exit fullscreen mode

Pros:

  • You have full control over accessibility:
    • Add <title> and <desc> for screen readers.
    • Use role="img" and aria-* attributes.
  • Screen readers can interpret the SVG directly.
  • Fully navigable in the accessibility tree.

Cons:

  • More verbose in the HTML.
  • You must manually manage ids and aria references for accessibility.

🚫 3. SVG as Background Image – Not Accessible

background-image: url('icon.svg');
Enter fullscreen mode Exit fullscreen mode

Pros:

  • Clean for purely decorative icons.

Cons:

  • Not accessible to screen readers at all.
  • Treated as a decorative style, not as content.
  • Can't provide alt text or semantic meaning.
  • Should only be used for purely decorative graphics.

⚠️ 4. SVG as <img> – Limited Accessibility

<img src="icon.svg" alt="A sky blue circle icon">
Enter fullscreen mode Exit fullscreen mode

Pros:

  • Uses the standard alt attribute.
  • Treated like any other image: accessible if alt is meaningful.
  • Good for simple icons, logos, or illustrations.

Cons:

  • Cannot describe or access inner elements.
  • Can't be made interactive.
  • Can’t use SVG-native accessibility features like <title> or <desc> unless you're using <object> or inline SVG.

🎯 Recommendation Based on Accessibility

Use Case Recommended Approach
Interactive icons Inline SVG
Decorative backgrounds CSS background image (with aria-hidden)
Semantic, non-interactive icons <img> with descriptive alt
Rich SVG with built-in a11y <object> (only if SVG is authored well)

QA Time:

1. 🧠 What are <title> and <desc> in SVG?

Let's revisit the use of <title> and <desc> elements inside SVGs one more time. These elements are crucial for accessibility, especially when SVGs are inline and part of meaningful content (like icons, logos, or illustrations conveying info).

Element Purpose
<title> Gives the SVG a short, accessible name (like alt text for images).
<desc> Provides a longer, optional description (context or explanation).

They are read by screen readers and help users who can’t see the image understand its meaning.

✅ Basic Example

<svg role="img" aria-labelledby="svgTitle svgDesc" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <title id="svgTitle">Information icon</title>
  <desc id="svgDesc">A blue circle with a lowercase letter i in the center</desc>
  <circle cx="50" cy="50" r="45" fill="skyblue"/>
  <text x="50" y="60" font-size="40" text-anchor="middle" fill="white">i</text>
</svg>
Enter fullscreen mode Exit fullscreen mode

🧩 Key Parts:

  • role="img": Tells assistive tech this is an image, not just a decorative shape.
  • aria-labelledby="svgTitle svgDesc": Connects the text to the SVG.
  • <title>: Serves like alt text.
  • <desc>: Optional, adds detail.

🗂 When to Use Them

Use Case Use <title>? Use <desc>?
Logo or brand icon ✅ Yes Optional
UI icon with meaning ✅ Yes Optional
Decorative image ❌ No ❌ No
Complex charts or infographics ✅ Yes ✅ Yes

For decorative icons, you should instead use:

<svg aria-hidden="true" focusable="false" ...>
  <!-- no title or desc -->
</svg>
Enter fullscreen mode Exit fullscreen mode

2. Can svg omit the xmlns?

Yes — when used inline inside an HTML document, the xmlns attribute is not required.

So this is perfectly valid inline HTML5 SVG:

<svg role="img" aria-labelledby="titleId descId">
  <title id="titleId">Blue circle</title>
  <desc id="descId">A simple circle shape filled with sky blue</desc>
  <circle cx="50" cy="50" r="40" fill="skyblue" />
</svg>
Enter fullscreen mode Exit fullscreen mode

This works fine in modern browsers and supports accessibility.

⚠️ When is xmlns required?

Only in these cases:

Context xmlns Required? Why?
Inline in HTML ❌ No Handled by browser’s HTML parser
SVG file (standalone .svg) ✅ Yes Required for XML validation
Inline in XHTML ✅ Yes Because XHTML is XML-based
Copied into XML/MathML ✅ Yes Needs proper XML namespacing

Example for standalone SVG files:

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <circle cx="50" cy="50" r="40" fill="skyblue" />
</svg>
Enter fullscreen mode Exit fullscreen mode

Without the xmlns, the file won't validate as an SVG document and could cause rendering issues in some tools or older XML-based workflows.

🧪 Tips and Gotchas

🔢 1. Use Unique ids

Avoid duplicate ids like title or desc, especially in SPAs or when using SVGs multiple times.

<title id="infoIconTitle">Info icon</title>
Enter fullscreen mode Exit fullscreen mode

♿ 2. Make It Focusable if Interactive

If the SVG is clickable (like a button):

<svg role="img" tabindex="0" ...>...</svg>
Enter fullscreen mode Exit fullscreen mode

Or better: wrap it in a <button> or add keyboard handlers.

⚠️ 3. Don’t Rely on <title> as a Tooltip

Browsers often don’t show the SVG <title> as a tooltip like they do for HTML. Use title="" on the container element or tooltips for visual hints.

🛠️ 4. Screen Reader Testing

Test with real screen readers (VoiceOver, NVDA, etc.) — support is decent but can vary slightly between them.

Test the examples live.

And that's a wrap!

Top comments (0)