How to make transparent part of SVG clickable?

Sam Sabin picture Sam Sabin · Mar 15, 2014 · Viewed 11.2k times · Source

I have an SVG that uses :hover to change color. It only works when I hover over the solid part of the SVG, not the transparent part. I'm wondering how you could make the SVG interact with the mouse hovering anywhere over the whole SVG. The point of this is to make the SVG a link and the link only clickable on certain portions of the SVG. I don't just want a solution to this particular instance but a solution that works for many instances (If I wanted different parts of the SVG clickable.) The elements in my SVG are directly connected to CSS and grouped with a <g> tag to group the clickable elements.

Edit: the SVG is in an object tag

SVG

<?xml-stylesheet type="text/css" href="svg.css" ?>
<svg xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg3036" version="1.1" inkscape:version="0.48.2 r9819" width="58" height="58">
         <g class="test">
  <path d="M 8.1 32.8 C 7.1 30.1 0.3 -4.6 11.1 4.9 21.9 14.5 15.9 12.8 29 12.8 42.1 12.9 36.1 14.6 46.9 5.1 57.7 -4.5 50.9 30.3 49.9 32.9 48.9 35.6 37.6 54.8 29 54.7 20.4 54.6 9.1 35.4 8.1 32.8 z" id="path3119" inkscape:connector-curvature="0" sodipodi:nodetypes="zzzzzzz" class="wolf"/>
  <path d="M 31.5 23.3 46.6 21" id="path5212" inkscape:connector-curvature="0" sodipodi:nodetypes="cc" class="eyes"/>
  <path d="M 33 23 C 32.3 33.9 45 22 45.2 21" id="path5260" inkscape:connector-curvature="0" sodipodi:nodetypes="cc" class="eyes"/>
  <path sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path5262" d="M 26.5 23.3 11.4 21" class="eyes"/>
  <path sodipodi:nodetypes="cc" inkscape:connector-curvature="0" id="path5264" d="M 25 23 C 25.7 33.9 13 22 12.8 21" class="eyes"/>
  </g>
</svg>

CSS

.wolf{
    fill:   none;
    fill-opacity:   0;
    stroke-width:   3.672px;
    stroke-linejoin:    round;
} /*.wolf:hover {
    stroke: #777777;
}*/

.eyes{
    fill:   none;
    fill-opacity: 0;
    stroke-width:   1.26708329px;
}

.test {
    stroke: #5ff6ff;
} .test:hover {
    stroke: #555555;
}     

JSfiddle

Answer

Erik Dahlstr&#246;m picture Erik Dahlström · Mar 17, 2014

SVG2 adds a new keyword bounding-box to 'pointer-events' to make this easier. It applies to groups as well as to shapes, in your example it would become:

.test {
  pointer-events: bounding-box;
  stroke: #5ff6ff;
}
.test:hover {
  stroke: #555555;
}

See jsfiddle. Right now that should work in Chrome Canary or Opera Dev builds.

It depends on the shapes, but it's possible to get it working in the currently shipping browsers too. E.g by using pointer-events="all" on the largest shape, and then using CSS selectors creatively to get the stroke applied where you want it. It's a bit tricky since you probably want the stroke to apply to the group although the actually hovered element is the shape inside the group.

Another alternative is to script it using mouseenter and mouseleave events on the <g> element.