# Image Sprites An image sprite is a collection of images put into a single image or file. Helps reduce the number of HTTP requests, memory and bandwidth usage. They are often used to significantly improve performance in emoji selectors. ## Raster Sprites

How to create a WebP emojis sprite.

Download [ImageMagick][imd]. Create an image sprite using the [Montage][imm] tool: ```bash montage png/*.png -background none -geometry +0+0 PNG32:sprites.png ``` Convert the image to [WebP][imw] image format: ```bash magick sprites.png -quality 100 -define webp:lossless=true -define webp:method=6 sprites.webp ``` Suppose we have an image sprite with `72x72` emojis from [Unicode 16.0][u16]. Use the following JavaScript code to calculate the background size and position: ```js const size = 72; // size of each emoji const width = 4536; // image sprite width const height = 4464; // image sprite height const horizontal = width / size; // max number of emojis per row (63) const vertical = height / size; // max number of emojis per column (62) // Calculate the background size. // 100% is the size of the element that has the background image. // We need to multiply by the number of emojis per row and column. console.log('Background width:', 100 * horizontal); // 6300% console.log('Background height:', 100 * vertical); // 6200% // CSS -> background-size: 6300% 6200% // Calculate the emoji position at column 48, row 56. // Column 1 and row 1 are always 0%, the max is 100%. const position = calcPosition(48, 56); console.log('Background position X:', position.x); // 75.806% console.log('Background position Y:', position.y); // 90.164% // CSS -> background-position: 75.806% 90.164%; function calcPosition(col, row, d=3) { const x = 100 / (horizontal - 1) * --col; const y = 100 / (vertical - 1) * --row; return { x: x.toFixed(d), y: y.toFixed(d) }; } ``` HTML example of how to use the WebP image sprite: ```html

```
## Vector Sprites (SVG)

How to use the <​use> element to reference SVG images.

Use the [``][use] element to reference only a part of an SVG image defined elsewhere. ```html

``` The [svg-sprite][ssp] library can be used to create SVG sprites of several types. The following example combines `icons/*/*.svg` into a single file for each subdirectory. ```js import fs from 'node:fs'; import path from 'node:path'; import SVGSpriter from 'svg-sprite'; if (!fs.existsSync('sprites')) fs.mkdirSync('sprites'); const iter = fs.globSync('icons/*/*.svg'); const groups = Object.groupBy( Array.from(iter), icon => icon.split(path.sep).at(-2) ); for (const [sprite, icons] of Object.entries(groups)) { const spriter = new SVGSpriter({ mode: { symbol: { inline: true } } }); for (const icon of icons) { const name = `icon:${sprite}.${path.basename(icon)}`; spriter.add(name, null, fs.readFileSync(icon, 'utf8')); } const output = `sprites/${sprite}.svg`; const { result } = await spriter.compileAsync(); for (const mode of Object.values(result)) fs.writeFileSync(output, mode.sprite.contents, 'utf8'); } /* INPUT -------------------------------------------------- ./icons/ misc/ circle.svg square.svg emojis/ butterfly.svg OUTPUT -------------------------------------------------- ./sprites/ misc.svg emojis.svg USAGE -------------------------------------------------- */ ```

How to use the <​img> element to display SVG images.

Use the [``][img] element with a [fragment identifier][fra] to display only a part of an SVG image. Using [SVG Fragment Identifiers][sfi] with [``][img] has a couple of advantages over other methods: - Only a single HTML element is required. - The [``][img] element behaves similarly to inline text: - When copied, the `alt` attribute text is included in the clipboard. - It can be selected, which makes it ideal for emoji-like icons in text. - Natively supports fallback behavior if the image or fragment fails to load. However, it's worth noting that `` with [``][use] remains valuable for: - Reusable SVG symbols in contexts where you need finer control (e.g., altering fill, stroke). - Interactive or animated graphics where direct access to the DOM structure of the SVG is needed. ```html ``` ```html circle square ```
[imd]: https://imagemagick.org/script/download.php [imm]: https://imagemagick.org/script/montage.php [imw]: https://imagemagick.org/script/webp.php [bgi]: https://developer.mozilla.org/docs/Web/CSS/background-image [bgs]: https://developer.mozilla.org/docs/Web/CSS/background-size [bgp]: https://developer.mozilla.org/docs/Web/CSS/background-position [use]: https://developer.mozilla.org/docs/Web/SVG/Element/use [img]: https://developer.mozilla.org/docs/Web/SVG/Element/img [fra]: https://developer.mozilla.org/en-US/docs/Web/URI/Fragment [u16]: https://www.unicode.org/versions/Unicode16.0.0 [sfi]: https://www.w3.org/TR/SVG/linking.html#SVGFragmentIdentifiers [ssp]: https://github.com/svg-sprite/svg-sprite