camlewis
camlewis

Reputation: 55

Changing CSS with SVG <symbols> on hover

I'm working on a handful of SVG icons as <symbol> that I want to be able to alter on :hover, :focus, and :active. Specifically, I need to be able to change the color of specific paths within an SVG. Normally, with any other element, I can do something like this

.parent .child {
    fill: blue;
}
.parent:hover .child {
    fill: red;
}

However, when applying this to my SVG symbols, it just doesn't work. Not many discussions from what I can find in the last couple of years on problems changing css with shadow-DOM stuff like SVG symbols, but the just using CurrentColor won't work for me because I need to do it with two colors.

I have a CodePen up with my scenario here

It seems like this should be straightforward but I've been tied up in knots over it for awhile. Anybody have any thoughts that might help?

Thanks in advance!

Upvotes: 5

Views: 1764

Answers (2)

Sphinxxx
Sphinxxx

Reputation: 13057

A similar question was asked here: SVG USE element and :hover style

The problem is that elements that are referenced by use aren't really part of the DOM, so you can't access them with CSS. However, some properties that are set on the use element itself (like fill or color) will trickle down to the referenced elements.

So, first of all, our CSS can only change the use element. Then we need to use some of the tricks in the article @Matheus mentioned to handle the different colors. This means changing the SVG code for the symbols a little. If the icons only need two colors per state, we can use fill + color/currentColor:

<g id="icon_alarm">
    <g class="transflip">
        <path class="transflip" d="M8 1.3c-3.6 ....." />
        <path class="transflip" d="M1 5.1C1.7 3....." />
    </g>
    <g class="fillflip">
        <path class="fillflip" fill="currentColor" d="M11.7 8......" />
    </g>
    ...

.icon use {
    fill: transparent;
    color: #007fa3;
}
.icon:hover  use {
    fill: #007fa3;
    color: transparent;
}

If the icons need more colors per state, we can use CSS variables and add style="fill: var(--my-special-color)" styles in the SVG (also a trick from the mentioned article), but that doesn't work in some browsers, e.g. IE/Edge.

Updated pen using both techniques: https://codepen.io/Sphinxxxx/pen/GMjgxJ?editors=1100

Upvotes: 1

jack
jack

Reputation: 1391

html:hover .transflip {
  fill: red;
}

This kind of hover works. I noticed you used same class for g and path. I'd try not to.

I'd also try to wrap each svg inside a div with width and height, and then use :focus etc. on that div since svg elements seem not to recognize pseudoselectors on your pen.

Upvotes: 0

Related Questions