SVG Interactivity

Beginner
⏱️ 9 min read
📚 Updated: Aug 2025
🎯 2 Examples
Events

What You’ll Learn

SVGs aren’t just static graphics—you can make them respond to clicks, hover, touch, and keyboard interactions. That’s how modern dashboards, maps, icons, and micro-interactions are built.

This guide shows how to attach events with JavaScript, how to style interactions with CSS (:hover, :focus-visible), and how to make interactive SVG elements accessible.

⚡ Quick Reference — Interactive SVG

Mouse / Touch click

Toggle state, open dialog, navigate

Hover :hover

Highlight shapes with CSS

Keyboard tabindex

Make SVG focusable

A11y aria-label

Describe interactive controls

Hit testing pointer-events

Control what can be clicked

Basic Event Listener
element.addEventListener('click', function () {
  // handle interaction
});

👀 Live Preview — Hover & Click

These mini demos are always visible. The full, copy-ready examples are below.

CSS hover highlight
Click to toggle
1

Click to Toggle State

A simple interactive SVG button: click (or press Enter/Space) to toggle the rectangle colour. This includes keyboard support and a visible focus ring.

index.html
<!DOCTYPE html>
<html>
<head>
  <style>
    #toggleRect{cursor:pointer;transition:fill 160ms ease,transform 160ms ease}
    #toggleRect:hover{transform:translateY(-1px)}
    #toggleRect:focus-visible{outline:none}
    #toggleRect.is-focus{stroke:#0f172a;stroke-width:3}
  </style>
</head>
<body>

<svg width="240" height="160" viewBox="0 0 240 160">
  <rect id="toggleRect" x="55" y="35" width="130" height="90" rx="16" fill="#2563eb"
        tabindex="0" role="button" aria-label="Toggle rectangle color" />
</svg>

<script>
  const rect = document.getElementById('toggleRect');
  function toggle() {
    const isBlue = rect.getAttribute('fill') === '#2563eb';
    rect.setAttribute('fill', isBlue ? '#ef4444' : '#2563eb');
  }
  rect.addEventListener('click', toggle);
  rect.addEventListener('keydown', function (e) {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      toggle();
    }
  });
  rect.addEventListener('focus', function(){ rect.classList.add('is-focus'); });
  rect.addEventListener('blur', function(){ rect.classList.remove('is-focus'); });
</script>

</body>
</html>
Try It Yourself
2

Hover Highlight (CSS) + Tooltip (JS)

A lightweight pattern: use CSS for hover styling and JavaScript only to show contextual information. This keeps the interaction smooth and fast.

index.html
<svg width="320" height="160" viewBox="0 0 320 160">
  <style>
    .chip{cursor:pointer;transition:transform 140ms ease,opacity 140ms ease}
    .chip:hover{transform:translateY(-2px);opacity:0.95}
    .chip:focus-visible{outline:none}
    .chip.is-focus{stroke:#0f172a;stroke-width:3}
  </style>

  <g id="chipA" class="chip" tabindex="0" role="button" aria-label="Blue chip">
    <rect x="32" y="44" width="120" height="72" rx="18" fill="#3b82f6" />
    <text x="92" y="86" text-anchor="middle" font-size="14" fill="white" font-family="system-ui,Segoe UI,Arial">Blue</text>
  </g>

  <g id="chipB" class="chip" tabindex="0" role="button" aria-label="Green chip">
    <rect x="168" y="44" width="120" height="72" rx="18" fill="#10b981" />
    <text x="228" y="86" text-anchor="middle" font-size="14" fill="white" font-family="system-ui,Segoe UI,Arial">Green</text>
  </g>
</svg>

<div id="tip">Hover or focus a chip</div>

<script>
  const tip = document.getElementById('tip');
  function bindChip(id, msg) {
    const el = document.getElementById(id);
    if (!el) return;
    function show(){ if (tip) tip.textContent = msg; }
    el.addEventListener('mouseover', show);
    el.addEventListener('focus', function(){ el.classList.add('is-focus'); show(); });
    el.addEventListener('blur', function(){ el.classList.remove('is-focus'); });
    el.addEventListener('keydown', function(e){
      if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); show(); }
    });
  }
  bindChip('chipA', 'Blue chip: click to select (demo)');
  bindChip('chipB', 'Green chip: click to select (demo)');
</script>

🧠 How It Works

1

Pick a target element

You can attach events to most SVG elements: <rect>, <circle>, <path>, or grouped elements in <g>.

Select
2

Use CSS for hover/focus

Keep interactions snappy by using CSS for presentation: :hover, :focus-visible, transitions, and transforms.

CSS
3

Attach JS events

Add event listeners like click, mouseover, or pointerdown using JavaScript. Update attributes with setAttribute or toggle CSS classes.

JavaScript
4

Make it accessible

If it behaves like a button, add tabindex="0" and role="button". Also handle Enter and Space so keyboard users get the same behavior.

A11y
=

Interactive, responsive UI

By combining CSS for visuals and JS for state, SVG becomes a powerful UI building block for the modern web.

💡 Best Practices

Do

  • Use CSS for hover animations and transitions whenever possible
  • Use pointer cursor to communicate clickability
  • Add tabindex, role, and aria-label for interactive controls
  • Prefer pointer events (pointerdown, pointerup) for cross-device input
  • Keep hit targets large enough for touch (44px+ is a good rule)

Don’t

  • Rely on hover-only interactions—touch devices don’t have hover
  • Make clickable elements with fill="none" and no stroke (no hit area)
  • Forget keyboard users when building button-like interactions
  • Attach dozens of high-frequency listeners without considering performance
  • Hide focus outlines without providing an alternative focus style

Key Takeaways

1

SVG elements can handle events like HTML elements

2

Use CSS for hover/focus effects and JS for state changes

3

Add tabindex and handle Enter/Space for accessibility

4

pointer-events helps control hit testing and click behavior

5

Design interactions that work well on mouse, touch, and keyboard

❓ Frequently Asked Questions

Select the SVG element and attach a click event listener. If it behaves like a button, add tabindex="0", role="button", and handle Enter/Space for keyboard users.
Yes. SVG elements support CSS selectors like :hover and :focus-visible. You can animate fill, stroke, opacity, and transforms.
It controls whether the element can receive mouse/touch events. For example, you can disable hit testing on an overlay so clicks go through to the shape underneath.
Add tabindex="0" so it can receive focus, provide an aria-label (or <title>), and handle keydown so Enter and Space activate the same behavior as click.
Check for overlays covering the element, pointer-events settings, and whether your element has a clickable paint region (e.g. it isn’t fill="none" with no stroke). Also ensure the listener is attached after the SVG is in the DOM.

Draw Your Next Shape

Continue with SVG lines and learn how to control stroke width, caps, and positioning.

SVG Line →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful