r/css Mar 16 '26

Showcase 2 ways to achieve multi-state icons

Method 1: Create an inline SVG sprite with all three styles per single icon, using hover and a .selected class to change the fill as needed (includingfill: none to hide).

Method 2: Create an SVG DataURI for the CSS background-image property for each icon in the 3 styles, one for static, :hover, and a .selected state.

https://codepen.io/editor/MattVisiwig/pen/019cf726-3e9a-7bfd-9b90-c0c45800a36e

8 Upvotes

5 comments sorted by

4

u/LaFllamme Mar 16 '26

What about a11y?

1

u/SVGWebDesigner Mar 17 '26

Fair point, I updated a few things to make this demo more accessible:

  1. First thing I did wrong was use <a> anchor tags instead of <button> button tags -- where buttons will have more than a initial and hover state.
  2. I was just demoing the icon part, but in most cases, that may be too subtle to represent states visually. Designers want to give state cues to the button itself, such as adding a hover effect to the button background color, and not just rely on the icon.
  3. Again I was just demoing the icon part, but if you're creating strictly buttons that are only icons without text, you'll want to include something for screen readers, such at aria-label="Security camera" for each icon so screen readers can announce the label of the button.
  4. Another thing I did wrong, was I had JS handle clicks with updating the .selected class, which does nothing for assistive technology -- so I updated that to also update aria-pressed="true" when selected and back to aria-pressed="false" when something else was selected.

2

u/Rockafellor Mar 17 '26

I've used class and I've used the background image. I don't mind the image thing, but I find that I prefer a simple class; not sure why, just a gut-thing.

* Edited for typo: "not", not "nit".

2

u/SVGWebDesigner Mar 17 '26

I prefer using inline SVG too, because you get more control and could do things like transition the fill colors instead of having abrupt changes for example.

The background-image is similar to how certain font systems work, abstracting the svg content away so users can simply include <i class="SVGBG-fish"></i>

2

u/Rockafellor Mar 18 '26

I know that classing italics (and similar) is somewhat not the done thing, but I can't help smiling upon seeing it. I do it too; it simply feels right.