Creating an SVG icon sprite
If you use a lot of SVG icons on your website, it is better for the performance of the site to merge them into one file: the SVG sprite.
You can do this with the powerful svg-sprite
package by Joschi Kuphal.
- See svg-sprite
Install svg-sprite
with npm:
npm install --save-dev svg-sprite
Next, we put all configuration data in a configuration file called svg-sprite.config.json
:
{
"path": "out",
"mode": {
"view": {
"dest": "assets/icons",
"sprite": "sprite.svg",
"bust": false,
"example": false
}
},
"shape": {
"spacing": {
"box": "icon"
}
}
}
Make sure to change assets/icons
to your own directory where sprite.svg
should be generated.
It can also generate an example file (by using "example": true
) so you have an overview of all available icons.
See all options in the extensive documentation at svg-sprite configuration.
Note the "box": "icon"
. Using this, you can use SVG icons of various sizes in one sprite
and they will appear as expected using the technique below.
Now you can call svg-sprite
to generate the sprite.svg
from several SVG files.
npx svg-sprite --config src/svg-sprite.config.json src/icons/*.svg
Change src/svg-sprite.config.json
to the location of your config file
and change src/icons
to your own directory where the individual SVG files are.
For the examples on this page, we use a directory with these SVG icon files:
archive.svg
circle-user-round.svg
settings.svg
star.svg
trash-2.svg
It’s a good idea to include the script above into your package.json
, so it’s easy to run:
...
"scripts": {
...
"sprite": "svg-sprite --config src/svg-sprite.config.json src/icons/*.svg"
}
Now that we’ve generated a sprite.svg
, how do we use it?
We will use SVG fragment identifiers.
It sounds complicated, but it is very simple.
From now on, don’t use (for example) star.svg
as the location of your SVG file, but sprite.svg#star
.
The file name of the original SVG icon will be the part after the #
(the fragment identifier).
There’s no need to load an extra generated CSS file.
Now you can use one of the icons in an img
tag:
This is the HTML of the icon above:
<img width="100" height="100" src="/assets/files/sprite.svg#settings">
Or as a background image:
With the following HTML:
<style>
.bg-icon {
width: 100px;
height: 100px;
background: url(/assets/files/sprite.svg#archive) 50%/cover;
}
</style>
<div class="bg-icon"></div>
By using mask-image
, you can give the icons a color.
Make sure the source icons are black and white.
This is the CSS code of the example above:
.hover-icon {
width: 100px;
height: 100px;
background-color: lightblue;
mask-image: var(--location);
mask-size: 100px 100px;
transition: background-color 500ms ease;
&:hover {
background-color: steelblue;
}
}
.icon-list {
display: flex;
gap: 1rem;
padding: 40px 20px;
list-style: none;
}
And the HTML:
<ul class="icon-list">
<li><div class="hover-icon" style="--location: url(/assets/files/sprite.svg#star)"></div></li>
<li><div class="hover-icon" style="--location: url(/assets/files/sprite.svg#circle-user-round)"></div></li>
<li><div class="hover-icon" style="--location: url(/assets/files/sprite.svg#settings)"></div></li>
<li><div class="hover-icon" style="--location: url(/assets/files/sprite.svg#trash-2)"></div></li>
<li><div class="hover-icon" style="--location: url(/assets/files/sprite.svg#archive)"></div></li>
</ul>
Scroll to the side to see that the file names used are sprite.svg#star
, sprite.SVG#circle-user-round
etc.
Browser support
You can find browser support in Can I use: SVG fragment identifiers. If you want to support older browsers, then use the separate icon SVG files as a fallback. For modern browsers you can use the sprite.
Using SVG icons on the web
If you want to use more graphical effects using mask-image
, see my other article about SVG icons: