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?
Actually, the best way to solve this is... on the
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.
http://jsfiddle.net/energee/UL9k9/
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
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.
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.
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.
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
<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.
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)
<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:
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
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 MouseEvent that is considered "interactive" (such as click and mousedown, but not mouseenter) is sent to the nested browsing context inside the
With this style, the MouseEvents aren't sent into the
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)
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.
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>
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>
Success story sharing
img
with svg makes then unusable for changing internal SVG styles.