A CSS Sprite Generator

How do sprites work?

As is mentioned in what is a CSS sprite, a sprite is a single image file that contains more than one image. By combining multiple images into a single file, you can decrease the download time of a web page.

Ordinarily, when a web page is requested, the web browser has to download each image file in turn. It will parallelize some of these requests, but there will be limits to the number of requests that can be run at any one time. Historically, this limit was defined as just two, in the RFC for HTTP 1.1, but modern browsers no longer conform to this and may use more threads for downloading files from a single host. See this table from browserscope.org showing the number of connections per hostname.

When these blocking requests for images combine with requests for other resources, this can have a detrimental impact on the loading time of a web page. It can be common for a website to display many small images as part of its design, each of these images will need to be downloaded before being rendered on page.

Since page load time is a key factor in search engine optimisation, it is important to make sure that, wherever possible, images do not impact too negatively on the time it takes a web page to load.

What does a CSS sprite image look like?

Shown below is an example of the sprite image file used for this website. You can see that the image file is made up of more than one image and these images have been arranged in the sprite file at various positions. One of these segments is highlighted and the relative offset to its place in the image is indicated.

Example of a CSS sprite image

How do I extract images from a sprite image?

By utilising the background-image and background-position CSS properties, we can set the background image of an element to be the sprite image, and position this image to the offset of the component image we wish to display.

For example, extrating the highlighted image from the sprite file, we could configure a CSS class as follows:

    background-image: url( sprite-image.png );
    background-position: -426px -124px;
    width: 326px;
    height: 62px;

The offset to the top-left corner of the image is negative as we are moving the image by this many pixels, leftwards and upwards respectively. We set the maximum dimensions of the element using the width and height, which corresponds to the width and height of the image we wish to extract from the sprite file. If we didn't limit the bounds of the element by this amount, the remaining graphics to the right and below the image could be revealed.

It should be noted that no "display" property is set in this rule, as it is assumed that the element to which the class is applied shall dictate the display mechanism. However, it must be one of either block or inline-block for the width and height to be set appropriately.

Using sprite images in img tags for accessibility and SEO

Since the background-image property can be applied to any element, it is possible to apply this to the img tag as well. This can be important where a symantically relevant image for display on a website is defined within a sprite image.

The img tag provides the alt attribute, the purpose of which is to describe the content of the image. This alternative text provides users who are otherwise unable to see the image with some context for what the image is displaying.

Take, for example, an image which is embedded in a link. The alt attribute would, in normal circumstances, describe the purpose of the link, and what would occur were that link to be actioned. If we were to embed the image within the link by utilising the background-image property on the a tag itself, this information could be lost. It would, of course, be possible to add text inside the a tag, but we would need to hide this from a user who is able to see the image. In this circumstance, it may be best to rely on the img tag and utilise the existing mechanism for providing alternative text for describing an image.

Image alt text is also an important SEO ranking factor, so it's worth bearing in mind if you do decide to use symantically important images within a sprite file to ensure they are embedded appropriately into the HTML.

To use a sprite image with an img tag, it is necessary to supply an image that will be displayed by the img tag, otherwise a broken link image will be shown. A 1x1 pixel transparent image can be used for this purpose.

For example, see the image below which shows how the Sprite Thing homepage renders in a text-only web browser.

Sprite Thing website shown in text-only web browser to illustrate accessibility

What about Web Fonts?

Web fonts can be used to improve the stylistics of a web site without the need to rely on images. Web fonts definitely carry an overhead, aside from inconsitencies between which web fonts are best supported by different browsers and platforms, font files themselves can be relatively large. If used throughout a website and if they offer sufficient benefit to the presentation of the site, they're a useful design tool, but, if they're only used for a proportion of the site, or if the licence of the font that's required does not allow for use on the web (but does permit use in embedded images), the segements which require the use of the font could be created with images instead and embedded in a sprite file.

The sprite file used on this site contains headings, for example. Granted, this site isn't going to win any design awards, the images are chiefly to exemplify what could be done with sprites; and, besides, embedding images of headings feels old-hat these days. Certainly, some of the elements in the sprite image used on this site don't fit well for display on mobile devices. JavaScript could be used to scale the images down to fit, or distinct sprite files could be created for responsive designs. It would be possible to use media queries to serve up different sprite files for different screen sizes, and the manner in which CSS rules are processed would result in just one sprite files being acquired, possibly two if the landscape view demands a different sprite image from the portrait.

Other fonts which provide symbols for use on a webiste, such as Font Awesome, are great for providing a plethora of symbols and glyphs, but the client has to download the embedded font which could be over 100KB. Of course, the specific symbols used in the font could be cut down, but this would need to be managed and may be costly. Tools like Font Awesome can be great for quick development and prototyping, but not necessarily at release stage. Once a design has been created with a symbolic font, there's likely to only be a few dozen - at the most - of symbols used, which could easily be extracted from the design and incorporated within a sprite image.

CSS Sprites for mobile and responsive websites

Briefly touched on in the earlier segment, mobile and responsive websites may require different sprite files depending on the view that's being presented. This can vary in both terms of the size of the viewport, but also the pixel density of the device displaying the sprites.

As of writing, this site uses just a single sprite file which is best for desktop browsing - for both "standard" screen resolutions and pixel densities. When viewed on a mobile device, it suffers from two problems: firstly, the larger images expand beyond the size of the viewport; and second, the images look pixellated on a high-density screen as they are scaled up.

There are a couple of ways of tackling the first issue. We could utilise JavaScript to isolate any sprite objects which extend beyond the size of the viewport. We could then use the background-size property to scale the sprite image to fit for the object to be displayed and calculate its relative offset based on the scale factor from the original sprite image. (There is an implementation of this on Sprite Thing, it's not perfect, but it gives you an idea). Alternatively, we could serve different sizes of sprite image for display on different screen sizes and utilise @media queries to determine when to supply which sprite image, and set other CSS rules accordingly.

To rectify the issue of scaling problems as seen on higher density screens, the (non-standard) media query for device pixel ratio -webkit-device-pixel-ratio would allow different density sprite images to be served for use on devices with higher pixel densities. Ben Frain has a full list of vendor specific options for -device-pixel-ratio.

Continue reading
What is a CSS sprite?
How do I use Sprite Thing?
Get started
Go create your CSS sprite