Explain CSS sprites, and how you would implement them on a page or site.
Published: 2022-06-28 06:17:18

CSS Sprites are mostly related to creating icons for a site or an app. It is also commonly used for animations in games. Here, we'll cover icons.

**What**
They combine all icons into **one** image file. And different icons are referenced by either their pixel position using `background-position` property or by the svg `<use>` tag.

Normally, we use icons delivered via CDNs by various icon providers like Fontawesome or IcoMoon. But their sizes are generally large because they send an entire icon system to the browser. The icons are fetched one by one from the CDN, which delay their load times.

With CSS Sprites, we are able to reduce the size of the icon system by selecting only the icons we use in our app. We also reduce the number of HTTP requests because we combine all icons into one file and deliver it to the client in one response. This makes individual icons available to the browser faster.

**How**
Before we can use CSS Sprites, we have to generate an image file using a **sprite generator**. Various sprite generators are available online or as **npm packages**. We can use two types of sprites: **png** or **svg**.

**.png Sprites**
With png sprites, we place the image as a **background image** to a `<div>`. Important thing to note here is that we are using the **entire** image full of icons as the background image. And then the idea is to focus on our icon of interest using the `background-position` property, the width and height of the icon.

The `background-position` property sets the starting point of the background image to be used in the `<div>`. If our icon is `48px` inside the image **horizontally**, we set `background-image-x: -48px;`, which basically hides everything between `0` and `48px`. If  it is `32px` inside vertically, we set `background-position-y: 32px;`, which hides everything from 0-32px vertically. We hide the icons that come after by setting the `width` and `height` of our `<div>` to the width, height, padding and margin of the icons themselves.

See and example of png sprites in [this codepen](https://codepen.io/anewman15/pen/vYRBdpb).

One drawback of using png sprites is we cannot style our sprite they way we want, for example change its color for a certain state of the icon. We have to include a sprite for each color and shade of the same sprite.

**.svg Sprites**
Sprites using an `.svg` file take a different approach. There is no background involved. The steps involve:

- Generating an `.svg` sprite file using online tools or **npm packages** like [this one](https://github.com/frexy/svg-sprite-generator). In the output sprite, each icon image is placed in an svg `<group>` or `<symbol>` tag with its `id` attribute specified.
- Including the sprite file at the **top** of the HTML document. This is important, because the sprite `id`s must be available before the icons can be referenced later in the document. There are several ways of doing this. One method is to use an `<object>` element.
```
<object data="sprite.svg" type="image/svg+xml" style="display: none;">
  ...
</object>
```
Another important thing is to set `display: none;` for the `<object>` element.
- Then in the section where we want to add an icon, we add an `<svg>` element. Inside the `<svg>` element, we put an `<use>` tag and reference the icon of our choice with its `id` defined in the sprite file.

```
<div class="social-links">
  <svg viewBox="0 0 32 32" class="icon icon-facebook">
    <use href="#facebook-square"></use>
  </svg>
</div>
```
- We can then style the `<svg>` icon with a `class` anyway we want.

For an example, see [this pen](https://codepen.io/anewman15/pen/PoRYRPN).

---
References
1. [CSS Image Sprites](https://www.w3schools.com/css/css_image_sprites.asp)
2. [Implementing image sprites in CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Images/Implementing_image_sprites_in_CSS)
3. [Icon System with SVG Sprites
](https://css-tricks.com/svg-sprites-use-better-icon-fonts/)
4. [Using SVG](https://css-tricks.com/using-svg/)