3 ms·
I like to use sprite files for conditional styling of icons, because using separate file for each state creates a visible delay on state changes, which doesn't
by panstromek 2y ago
I like to use sprite files for conditional styling of icons, because using separate file for each state creates a visible delay on state changes, which doesn't look great.
You can make them with <defs> and <use> tags pretty easily if you understand svg a bit. I usually bundle two-state icon into a single svg file, and then use `object-position: left/right` property on the <img> tag to switch between the variants. You can also combine this with some simple css animations.
- mrled 2y agoOh man, you're right, I didn't realize they worked this way. This basically means there is no compromise at all, I'm going to update the post. Thanks!
- panstromek 2y agoWell, there's still a compromise to be fair. It's defintely more work to manage these sprites and it's especially annoying when there's more than one state. I think it's possible to write some tool to automate it, but I haven't found one.
- deleted 2y ago[deleted]
- douglee650 2y agoThere are preprocessors that will do this. Conceptually, we would: include sprite-1.snippet include sprite-2.snippet and it would write the defs into the page. Then later in the page, `<use>` the defs you included.
- WhyNotHugo 2y agoAny examples of further material on this? Sounds pretty convenient, but I'm not familiar with <def> or <use> (or `object-position`, for that matter).
- panstromek 2y agoIt's something like this (I just quickly took this from my project, not sure if it works in this form now). This one uses the defs/use trick to reuse a path, but you can also just put two different svgs next to each other and not use the defs/use at all. The icon: <!-- the icon width is 2x wider, to accommodate both 26x26 variants --> <svg xmlns="http://www.w3.org/2000/svg" width="52" height="26"> <defs> <!-- here's the icon defined, you can basically put anything here and mark it with an id (you can even use another svg) --> <path id="icon" path="..."/> </defs> <!-- first variant with no fill --> <use stroke="#fff" href="#icon"/> <!-- second variant with fill, shifted by 26 (dimensions of the icon) --> <use x="26" fill="#00ACA0" stroke="#00ACA0" href="#a"/> </svg> HTML: <!-- make sure you use dimensions of the single variant --> <img src="icon.svg" width="26" height="26" class="hover-icon"> CSS: .hover-icon { /* make sure that only first block of the image is visible */ object-fit: cover; object-position: left; } .hover-icon:hover { object-position: right; }
- myfonj 2y agoSandbox (with fixes): https://codesandbox.io/p/sandbox/pan-stromek-svg-object-position-q6nxrr https://codesandbox.io/p/sandbox/pan-stromek-svg-object-posi... Btw, for such simple re-colouring I'd probably rather used CSS hue shift filter or similar effect, and kept the SVG "dumb". But for having different shapes or geometric properties this approach is indeed nifty.
- panstromek 2y agoYes, I do that, too. The benefit of using the sprite system is that it's pretty general, so once you have some CSS for it, it's easy to keep adding new icons. CSS filters are usually more special for each case, but I use them too (mostly for brightness and greyscale things that are repeated on multiple places, e.g. tabs or disabled state).
- prutya 2y agoHey, I wrote a small blog post on <defs> and <use> and how to optimize icons using them: https://www.prudkohliad.com/articles/reuse-svg-icons-2023-08-14 https://www.prudkohliad.com/articles/reuse-svg-icons-2023-08...