1

All,

I'm pretty new to using SVGs, and I'm hoping someone here can explain to me how to target a particular element of my SVG with CSS?

What I'm trying to do is put together a country map where specific areas will appear darker when the user hovers over them. The map was made in layers in Photoshop, then imported in Illustrator and exported as a SVG file. So far, so good. But I'm running into trouble when I try to style their individual parts (which Illustrator put in "g" IDs and tags).

The code looks like this:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 1762 2043" style="enable-background:new 0 0 1762 2043;" xml:space="preserve" xmlns:xml="http://www.w3.org/XML/1998/namespace">

<g id="Area1">

        <image style="overflow:visible;" width="378" height="272" id="Area1" xlink:href=".../.../121F7A955DACD041.png" transform="matrix(1 0 0 1 657 912)">
    </image>
</g>

Followed by an "Area2", "Area3", etc.

Now I figured if I simply used "Area1:hover" in my stylesheet, it would work -- but it doesn't.

Oddly enough, when I set "display: none" for the same ID in my CSS, it DOES hide the area. So why won't the hover attribute work?

3
  • 1
    You're using the same id attribute on two different elements. id attributes should be unique for the page. Commented Aug 14, 2014 at 22:55
  • Does this do what you want? jsfiddle.net/jj5wqmze/2 Commented Aug 14, 2014 at 23:01
  • No, that puts a hover over the entire svg. I need specific hovers for parts of it. Commented Aug 15, 2014 at 10:28

2 Answers 2

2

The <g> element defines a group of SVG elements. It doesn't actually take up any space in the rendered SVG image. So there is nothing for you to :hover over in order to activate this rule in your stylesheet.

You can fix this by setting :hover rules for the group's child elements, or by adding a child selector to the CSS rule, like #Area1 > *:hover, for example.

Here's a simple example (JSFiddle link)

CSS:

#a1 > *:hover {
    fill:#fc0;
}

SVG:

<svg viewBox="0 0 200 200">
    <g id="a1" style="fill:#e82">
        <path d="M50,50v100h100v-100z" />
    </g>
</svg>

Update: Creating SVG maps with :hover style attributes

If you try to create an SVG map from multiple overlapping <image> elements, you're going to have problems in the overlapping parts because the :hover style is only applied to the topmost element, even if it only contains transparent pixels.

To fix this, you will have to apply an SVG clipping mask to each section of the map. Alternatively, you could create the map entirely from SVG elements. Here's an example of the latter approach.

Sign up to request clarification or add additional context in comments.

6 Comments

Targeting #Area1 > *:hover works! At least partially. It only works when I hover over the left part of the image. When I hover over the right part, nothing happens. Do you have any idea why that might be?
@user1136475 Impossible to say without seeing your code. Can you create a minimal example and add it to your question and/or post it at JSFiddle?
Here you go: jsfiddle.net/06seo0jz/2 Try hovering over the southwestern province ("Zeeland"). It works when you hover over the left part of it, not when hovering over the right part.
OK, you've got a problem there. The <image> elements are just rectangular blocks as far as mouse events are concerned. The only part of the Zeeland image that isn't covered by another image is that part on the left edge that appears to be working. Change your CSS selector to svg > g > image:hover and I think you'll see what I mean. You have two options: (1) add clipping masks to all your images and set the pointer-events attribute to visible, or (2) use filled paths instead of images.
Ah! Thanks for the explanation. I understand what's the problem now. Could you elaborate on the possible solutions though? Adding clipping masks is something I've have to do to the SVG in Illustrator, correct? Or can I do that with coding? As for using filled paths, you mean giving each of the "g" elements a background image?
|
0

I think your problem is that your group id (g tag) is the same id of your image element

<image overflow="visible" width="209" id="Area1" height="248" xlink:href="//www.elige-argentina.com/assets/img/mapa-argentina.png"  transform="matrix(1 0 0 1 612.6923 23.6923)">
</image>

Working Fiddle: http://jsfiddle.net/b2f2jx0f/3/

4 Comments

You have the id attribute defined twice.
I tried this solution. It's basically just setting the hover on the image and giving it a unique ID. Don't know why, but it doesn't work...
Kind of off topic but If you are making a complex design and know a bit of Javascript, I suggest you look at d3js.org. It could help you to work with svg. I make a map with hovers and zooms with it. unirelmundo.com/mapa_cruces
I would like to avoid Javascript if possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.