Skip to content

Instantly share code, notes, and snippets.

@bugoaneo
Forked from darsain/svg_sprites.md
Created January 26, 2023 14:38
Show Gist options
  • Select an option

  • Save bugoaneo/9408a46d5305ae245b0773e73b80ce8c to your computer and use it in GitHub Desktop.

Select an option

Save bugoaneo/9408a46d5305ae245b0773e73b80ce8c to your computer and use it in GitHub Desktop.
How to use SVG sprites in img[src] and css backgrounds

To make this work in CSS:

background: url('images.svg#chart');

or img:

<img src="images.svg#chart">

You need to structure images.svg in a way that enables SVG fragment identifiers. There are 3 ways I know of:

1. SVG stack with global viewBox

You'd use this when all images are the same size.

<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
	<defs>
		<style>
		.img { display: none }
		.img:target { display: inline }
		</style>
	</defs>

	<g id="chart" class="img">
		<rect x="6" width="4" height="16"/>
		<rect x="12" y="4" width="4" height="12"/>
		<rect x="0" y="8" width="4" height="8"/>
	</g>

	<!-- more "g" tags -->
</svg>
2. SVG stack with per image viewBox

You'd use this when every image has different size.

<svg xmlns="http://www.w3.org/2000/svg">
	<defs>
		<style>
		.img { display: none }
		.img:target { display: inline }
		</style>
	</defs>

	<svg viewBox="0 0 16 16">
		<g id="chart" class="img">
			<rect x="6" width="4" height="16"/>
			<rect x="12" y="4" width="4" height="12"/>
			<rect x="0" y="8" width="4" height="8"/>
		</g>
	</svg>

	<!-- more "svg > g" tags -->
</svg>
3. SVG sprite with ID'd views

This one is sub-optimal. When mismatching target element to image size ratio, you might see other sprites peeking from sides. You'd have to make big gaps between images, but that's ugly and not bulletproof.

It is also more annoying to write build scripts for. But here it is anyway:

<svg xmlns="http://www.w3.org/2000/svg">
	<view id="chart" viewBox="0 0 16 16"/>
	<view id="plus" viewBox="16 0 16 16"/>

	<g transform="translate(0 0)">
		<rect x="6" width="4" height="16"/>
		<rect x="12" y="4" width="4" height="12"/>
		<rect x="0" y="8" width="4" height="8"/>
	</g>

	<g transform="translate(16 0)">
		<mask id="m" x="0" y="0" width="1" height="1">
			<circle cx="8" cy="8" r="8" fill="white"/>
			<line x1="8" y1="3" x2="8" y2="13" stroke="black" stroke-width="2"/>
			<line x1="3" y1="8" x2="13" y2="8" stroke="black" stroke-width="2"/>
		</mask>
		<rect width="16" height="16" mask="url(#m)"/>
	</g>
</svg>

Currently, SVG fragment identifiers in CSS backgrounds work only in FF and IE, and will work in Chrome as soon as crbug.com/128055 is fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment