I won't work propperly in your browser because it doesn't support the latest techniques. Switch to Google Chrome. Close

Inline SVG hover states
with CSS (<use> tag)

The article is about a really, really, really! simple hover states trick when you use SVG’s with the <use> tag. [ medium.com article ]

I'm creating a “like” button with inline SVG's, CSS and a tiny bit of JavaScript to trigger some classes.

Kind of states

The button needs 4 kind of states. I generated the inline SVG sprite with IcoMoon and needed to combine those icons to a single button.

Default

Hover

Active

Active hover

Watch your children

Combining the paths into a SVG wrapper with the class 'icon' and adding classes to each individual icon. The child classes are going to depend on the parent 'icon' class.

<svg class="icon" viewBox="0 0 32 32">
<use class="default" xlink:href="#icon-star-d"></use>
<use class="hover" xlink:href="#icon-star-h"></use>
<use class="active" xlink:href="#icon-star-a"></use>
<use class="active-hover" xlink:href="#icon-star-a-h"></use>
</svg>

All paths, as you can imagine, are now placed on top of each other without any CSS markup.

Hide and Seek

Now CSS must help us do the trick. First I created 2 silent classes. (SCSS) This is just a opacity switch. You could also use display:none/block.

SVG icon

<svg class="icon" viewBox="0 0 32 32">
<use class="default" xlink:href="#icon-star-d"></use>
<use class="hover" xlink:href="#icon-star-h"></use>
<use class="active" xlink:href="#icon-star-a"></use>
<use class="active-hover" xlink:href="#icon-star-a-h"></use>
</svg>

After that I add the states as classnames in SCSS as children of the .icon class. Hide them by default except the default icon of course. Followed up by adding the different states.

.hover, .active, .active-hover {
@extend %icon-is-shy;
}

:hover

&:not(.active):hover {
.hover{
@extend %icon-isnt-shy;
}

.default{
@extend %icon-is-shy;
}
}

The hover part says: Only trigger me when I don’t have the ‘active’ class.
Next the active state is added. The active class is going to be added to the parent (.icon) with JavaScript.

.active

&.active{
.default{
@extend %icon-is-shy;
}
.active{
@extend %icon-isnt-shy;
}
}

.active:hover

&.active:hover{
.active{
@extend %icon-is-shy;
}
.active-hover{
@extend %icon-isnt-shy;
}
}

Making it work

The last part is a tiny part of JavaScript that triggers a class on the SVG tag. Which will add the .active class.

$(“.icon”).click( function() {
var c = $(this).attr(‘class’);

if(c == “icon active”){
$(this).attr(‘class’, ‘icon’);
return true;
}

$(this).attr(‘class’, ‘icon active’);
});

Demotime

This is my very first writing on the web,
so tips are welcome!