SVG links: make a shape, text or map region clickable

Wrap a shape or text in an SVG a element to make it a link. How links behave inline, in an object and in an img tag, with code for a clickable map.

Published

SVG has its own <a> element. Wrap it round a shape, a group or a piece of text, give it an href, and that part of the drawing becomes a link, with no script needed.

<svg viewBox="0 0 100 100" width="200">
  <a href="/contact/">
    <circle cx="50" cy="50" r="40" fill="teal"/>
  </a>
</svg>

Click the circle and the browser goes to the contact page. In Chrome the link behaved like an HTML one in every respect tested: the pointer became a hand over it, the Tab key reached it, and Enter followed it.

SVG <a>
Goes roundShapes, groups, text, images: anything its parent may hold, except another <a>
Attributeshref, target, rel, download and the others HTML links have
Clickable areaThe painted parts of the shapes inside it, not a rectangle round them
KeyboardFocusable, and followed with Enter in Chrome. The SVG 2 specification requires browsers to make links focusable and usable from the keyboard
Older spellingxlink:href, still accepted: see href and xlink:href

The clickable area is the row that matters. An HTML link is a box. An SVG link is exactly the shapes it contains, following the same rules as any pointer event. A circle with fill="none" and a stroke is a link only along its outline: in the test, a click in its empty middle did nothing and a click on the line followed the link. To make the whole inside respond, give the shape fill="transparent" or pointer-events="all". SVG events explains those rules.

A clickable map

Each region is a path inside its own link. A hover style on the link shows which region the pointer is over:

<style>
  .region:hover path,
  .region:focus path {
    fill: crimson;
  }
</style>
<svg viewBox="0 0 100 100" width="300">
  <a class="region" href="/north/" aria-label="North region">
    <path d="M 10 10 H 90 V 45 H 10 Z" fill="teal"/>
  </a>
  <a class="region" href="/south/">
    <title>South region</title>
    <path d="M 10 55 H 90 V 90 H 10 Z" fill="gold"/>
  </a>
</svg>

Two regions that turn red under the pointer or when reached with the Tab key, and go to their own pages when clicked.

A region that is only a shape has no text for a screen reader to announce, so each link needs a name. Both ways shown here worked in Chrome’s accessibility tree: aria-label on the link named it “North region”, and a <title> element as the link’s first child named the other “South region”. A <title> also shows as a tooltip on hover. Accessible SVG covers naming.

For a real map with dozens of regions, the pattern is the same. Open the file in the SVG viewer to find each region’s path, and wrap each one.

Linked text

A link can go round a whole <text> element, or sit inside one round a few words:

<svg viewBox="0 0 200 100" width="400">
  <a href="/guide/">
    <text x="10" y="30" font-size="16">Whole line</text>
  </a>
  <text x="10" y="70" font-size="16">
    Read <a href="/guide/" fill="teal" text-decoration="underline">the guide</a> first
  </text>
</svg>

The first line is a link from end to end. In the second, only “the guide” is. Clicking “Read” does nothing.

Unlike HTML, SVG gives link text no colour or underline of its own, so add them, as here with fill and text-decoration.

Opening in a new tab

target="_blank" works as in HTML:

<a href="https://example.com/" target="_blank" rel="noopener">
  <circle cx="50" cy="50" r="40"/>
</a>

Tested in Chrome, the click opened a second tab and left the first where it was.

PlacementDo links inside the SVG work?
Inline <svg> in the pageYes
The .svg file opened directlyYes
<object data="map.svg">Yes, but the new page loads inside the object’s box unless the link has target="_top"
<img src="map.svg"> or a CSS backgroundNo

An SVG shown through <img> is a flat picture: nothing in it can be clicked. In the test a click on a linked circle inside an <img> did nothing at all. Two remedies:

To link the whole picture, wrap the <img> in an HTML link:

<a href="/shop/">
  <img src="/logo.svg" alt="Shop home" width="200" height="200">
</a>

The same works with an inline <svg> inside an HTML <a>. The whole box of the image is then the link, empty corners included.

To keep separate links on separate shapes, the SVG has to be inline or in an <object>.

Inside an <object>, the SVG is a document of its own. A plain link replaces the SVG within the object’s rectangle and leaves the page round it in place. target="_top" sends the whole window to the new address. Relative addresses also resolve from the SVG file’s own location, not the page’s: in the test, href="two.html" in /sub/file.svg went to /sub/two.html.

A link is selected and styled like anything else: a:hover, a:focus-visible, svg a path. One difference catches people out in script. On an SVG link, link.href is not text but an object, and the address is in link.href.baseVal or link.getAttribute('href').

For actions that are not navigation, such as opening a panel on the same page, a link is the wrong element. Use a click handler, and make the shape focusable with tabindex="0": see SVG events.

Common problems

What you seeCauseFix
The link does nothingThe SVG is shown with <img> or as a backgroundInline the SVG, use <object>, or wrap the <img> in an HTML link
Only the outline is clickableThe shape has fill="none"fill="transparent" or pointer-events="all"
The new page appears inside a small boxThe SVG is in an <object>target="_top" on the link
A linked SVG file opens the wrong addressRelative href values are resolved from the SVG fileUse addresses that start with /, or full URLs
The link text looks like ordinary textSVG does not style linksSet fill and text-decoration
A link inside another link goes to the outer addressLinks cannot be nested: the inner one is ignoredMake them siblings
The file will not open after adding linksxlink:href used without declaring xmlns:xlinkUse plain href
A screen reader announces only “link”The link holds shapes and no textaria-label, or a <title> as its first child

Questions

Can you put links inside an SVG file? Yes. The <a> element is part of SVG, and links work when the file is opened in a browser or placed inline or in an <object>. They do not work where the file is shown as an image.

Do links survive in other programs? That depends on the program. Browsers follow them. Outside browsers it varies, and cutting or plotting software has no use for a link.

Can one link cover several shapes? Yes. Put all of them inside the same <a>, or put a <g> inside it. Each painted part is then clickable.

How do I change the cursor? A link shows the hand pointer already. For shapes that respond to script, set cursor: pointer in CSS.