I have an SVG object in my HTML page and am wrapping it in an anchor so when the svg image is clicked it takes the user to the anchor link.
<a href="http://www.google.com/">
<object data="mysvg.svg" type="image/svg+xml">
<span>Your browser doesn't support SVG images</span>
</object>
</a>
When I use this code block, clicking the svg object doesn't take me to google. In IE8< the span text is clickable.
I do not want to modify my svg image to contain tags.
My question is, how can I make the svg image clickable?
-
2This single issue is responsible for SVG not picking up years after its introduction. This kind of behavior is unthinkable.Tyler– Tyler2022年06月16日 08:35:42 +00:00Commented Jun 16, 2022 at 8:35
13 Answers 13
Actually, the best way to solve this is... on the <object> tag, use:
pointer-events: none;
Note: Users which have the Ad Blocker plugin installed get a tab-like [Block] at the upper right corner upon hovering (the same as a flash banner gets). By settings this css, that'll go away as well.
11 Comments
img with svg makes then unusable for changing internal SVG styles.I had the same issue and managed to solve this by:
Wrapping the object with an element set to block or inline-block
<a>
<span>
<object></object>
</span>
</a>
Adding to <a> tag:
display: inline-block;
position: relative;
z-index: 1;
and to the <span> tag:
display: inline-block;
and to the <object> tag:
position: relative;
z-index: -1
See an example here: http://dabblet.com/gist/d6ebc6c14bd68a4b06a6
Found via comment 20 here https://bugzilla.mozilla.org/show_bug.cgi?id=294932
7 Comments
Would like to take credit for this but I found a solution here:
https://teamtreehouse.com/forum/how-do-you-make-a-svg-clickable
add the following to the css for the anchor:
a.svg {
position: relative;
display: inline-block;
}
a.svg:after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left:0;
}
<a href="#" class="svg">
<object data="random.svg" type="image/svg+xml">
<img src="random.jpg" />
</object>
</a>
Link works on the svg and on the fallback.
3 Comments
You could also stick something like this in the bottom of your SVG (right before the closing </svg> tag):
<a xmlns="http://www.w3.org/2000/svg" id="anchor" xlink:href="/" xmlns:xlink="http://www.w3.org/1999/xlink" target="_top">
<rect x="0" y="0" width="100%" height="100%" fill-opacity="0"/>
</a>
Then just amend the link to suit. I have used 100% width and height to cover the SVG it sits in. Credit for the technique goes to the smart folks at Clearleft.com - that's where I first saw it used.
1 Comment
A simplification of Richard's solution. Works at least in Firefox, Safari and Opera:
<a href="..." style="display: block;">
<object data="..." style="pointer-events: none;" />
</a>
See http://www.noupe.com/tutorial/svg-clickable-71346.html for additional solutions.
3 Comments
block or inline-block on the parent <a>.inline-block in some cases, but block seemed to work well on other cases; I guess it depends on the enclosing blocks...The easiest way is to not use <object>. Instead use an <img> tag and the anchor should work just fine.
14 Comments
<img> with a reference to svg data doesn't always work as you expect, even in the latest version of Chrome :( stackoverflow.com/questions/15194870/… <object> tag and add a point-event: none; to make it clickable. It preserve access to your svg source code and allow you to dynamically manipulate it.To accomplish this in all browsers you need to use a combination of @energee, @Richard and @Feuermurmel methods.
<a href="" style="display: block; z-index: 1;">
<object data="" style="z-index: -1; pointer-events: none;" />
</a>
Adding:
pointer-events: none;makes it work in Firefox.display: block;gets it working in Chrome, and Safari.z-index: 1; z-index: -1;makes it work in IE as well.
3 Comments
object will now be in a lower stacking-context (under) than it's parent.I resolved this by editing the svg file too.
I wrapped the xml of the whole svg graphic in a group tag that has a click event as follows:
<svg .....>
<g id="thefix" onclick="window.top.location.href='http://www.google.com/';">
<!-- ... your graphics ... -->
</g>
</svg>
Solution works in all browsers that support object svg script. (default a img tag inside your object element for browsers that don't support svg and you'll cover the gamut of browsers)
2 Comments
<svg> element and not wrapping it at all didn't work?i tried this clean easy method and seems to work in all browsers. Inside the svg file:
<svg>
<a id="anchor" xlink:href="http://www.google.com" target="_top">
<!--your graphic-->
</a>
</svg>
3 Comments
This is very late, but I was wondering why energee's solution works: specifically, how the <object> element affects its parent elements.
tl;dr You cannot click on an anchor that has an <object> element in it because the click events are being captured by whatever is inside of the <object> element, which then doesn't bubble it back out.
To expand on the symptom described in the original question: not only will an <object> element inside an anchor element cause the anchor to become unclickable, it seems that an <object> element as a child of any element will cause click, mousedown, and mouseup events (possibly touch events too) to not fire on the parent element, (when you are clicking inside the <object>'s bounding rect.)
<span>
<object type="image/svg+xml" data="https://icons.getbootstrap.com/icons/three-dots.svg">
</object>
</span>
document
.querySelector('span')
.addEventListener('click', console.log) // will not fire
Now, <object> elements behave somewhat "like" <iframe>s, in the sense that they will establish new browsing contexts, including when the content is an <svg> document. In JavaScript, this is manifested through the existence of the HTMLObjectElement.contentDocument and HTMLObjectElement.contentWindow properties.
This means that if you add an event listener to the <svg> element inside the <object>:
document
.querySelector('object')
.contentDocument // returns null if cross-origin: the same-origin policy
.querySelector('svg')
.addEventListener('click', console.log)
and then click on the image, you will see the events being fired.
Then it becomes clear why the pointer-events: none; solution works:
Without this style, any
MouseEventthat is considered "interactive" (such asclickandmousedown, but notmouseenter) is sent to the nested browsing context inside the<object>, which will never bubble out of it.With this style, the
MouseEvents aren't sent into the<object>in the first place, then the<object>'s parent elements will receive the events as usual.
This should explain the z-index solution as well: as long as you can prevent click events from being sent to the nested document, the clicking should work as expected.
(In my test, the z-index solution will work as long as the parent element is not inline and the <object> is positioned and has a negative z-index)
(Alternatively, you can find a way to bubble the event back up):
let objectElem = document.querySelector('object')
let svgElemt = objectElem.contentDocument.querySelector('svg')
svgElem.addEventListener('click', () => {
window.postMessage('Take this click event please.')
// window being the outermost window
})
window.addEventListener('message', console.log)
Comments
I was using simply
<a href="#">
<img src="../../assets/images/logo.svg" alt="">
</a>
Which works fine except I was trying to apply a :hover state. What brought me here was when I used
<a href="#">
<object data="../../assets/images/logo.svg" type="image/svg+xml" class="logo">
</object>
</a>
I lost my link and noticed in DevTools that the link still appeared around the SVG, but the :hover state worked. Utilizing energee's elegant answer, my link worked, but of course I lost the :hover. So it looks like the object tag isn't a great solution for applying a :hover change to an SVG.
I am curious, why would you not use the img tag to display an SVG without anything special added to it, like :hover? Using the img tag also works with the a tag.
Comments
Just don't use <object>. Here's a solution that worked for me with <a> and <svg> tags:
<a href="<your-link>" class="mr-5 p-1 border-2 border-transparent text-gray-400 rounded-full hover:text-white focus:outline-none focus:text-white focus:bg-red-700 transition duration-150 ease-in-out" aria-label="Notifications">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="30"
height="30"><path class="heroicon-ui" fill="#fff" d="M17 16a3 3 0 1 1-2.83
2H9.83a3 3 0 1 1-5.62-.1A3 3 0 0 1 5 12V4H3a1 1 0 1 1 0-2h3a1 1 0 0 1 1
1v1h14a1 1 0 0 1 .9 1.45l-4 8a1 1 0 0 1-.9.55H5a1 1 0 0 0 0 2h12zM7 12h9.38l3-
6H7v6zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm10 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</svg>
</a>
1 Comment
Do it with javascript and add a onClick-attribute to your object-element:
<object data="mysvg.svg" type="image/svg+xml" onClick="window.location.href='http://google.at';">
<span>Your browser doesn't support SVG images</span>
</object>