Generate CSS Sprites in ASP.NET

Something that is very common on websites is small images that is used to make links and other things look better. These small images is either added as a background image for the link, or as a separate image. When you load these images, they are requested and downloaded separate. Since the browser only make a small number of requests at once, it can take a while before all images is loaded on the page. To solve this, you can use CSS Sprites.

When you use CSS Sprites, you use the same image file for all the images instead of having them in separate files. When you request the images, you only have to load one file to get them all. When you want to show a specific image, you use CSS to change focus to that image.

One example where it is used is at Google.com. They have one single image for the logo and all the small icons that are used. Because of that, you will only have to download one single image:

google

This is a common way to solve it, since it gives you better performance.

There are some cons using CSS Sprites though. It can be hard to update the images, and it can be hard to get a specific image in the sprite file.

To make it easier to do this without the need of extra work, you can use the new control created by Microsoft. This control takes all files in a directory, and mash them together in one new file. It also creates a new CSS file with classes which are used to get the right images.

To use this new control, we need to get the assemblies. The project is released under a “almost-open source license” since it´s still a beta, but will probably be open source when it´s released as RTW. The assemblies, the source code and a great documentation can be downloaded from CodePlex:

http://aspnet.codeplex.com/releases/view/50140

When we have the assemblies, we will have to create a new ASP.NET MVC project (I use a ASP.NET MVC 3 project with Razor), and add references to ImageOptimizationFramework and ImageSprite.

To be sure the images and the CSS is being generated, we must add this to web.config:

<httpModules>
  <add type="Microsoft.Samples.Web.ImageOptimizationModule" name="Microsoft.Samples.Web.ImageOptimizationModule"/>
</httpModules>

We now have everythin required. I am going to use three different images with this control (downloaded from http://www.iconaholic.com):

calendar card folder

These images will be transformed into one image, and we will use CSS Sprites to show the right one. To be able to use the Sprites control in ASP.NET, I create a new folder called App_Sprites in the root, and in that folder, I create a folder with the name “icons”. Every folder in App_Sprites creates it´s own image and css file, which means we don´t get one huge file with all images in all folders.

Normally, I would do this when displaying the images:

<ul>
    <li>
        <img src="/app_sprites/icons/calendar.png" />
        <a href="#">Link #1</a>
    </li>
    <li>
        <img src="/app_sprites/icons/card.png" />
        <a href="#">Link #2</a>
    </li>
    <li>
        <img src="/app_sprites/icons/folder.png" />
        <a href="#">Link #3</a>
    </li>
</ul>

These images will be downloaded separate, and three different requests will be made. Since I want to use Sprites I add this in the head:

@Microsoft.Samples.Web.ImageSprite.ImportStylesheet("~/App_Sprites/icons/")

And this in the body:

<ul>
    <li>
        @Microsoft.Samples.Web.ImageSprite.Image("~/App_Sprites/icons/calendar.png")
        <a href="#">Link #1</a>
    </li>
    <li>
        @Microsoft.Samples.Web.ImageSprite.Image("~/App_Sprites/icons/card.png")
        <a href="#">Link #2</a>
    </li>
    <li>
        @Microsoft.Samples.Web.ImageSprite.Image("~/App_Sprites/icons/folder.png")
        <a href="#">Link #3</a>
    </li>
</ul>

I use the Image helper here to send the path to the original image. The result for both methods is this:

rendered

The generated HTML for the Sprite control looks like this:

<link href="App_Sprites/icons/lowCompat.css" media="all" rel="stylesheet" type="text/css" />

And:

<ul>
    <li>
        <img class="icons_calendar-png" src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
        <a href="#">Link #1</a>
    </li>
    <li>
        <img class="icons_card-png" src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
        <a href="#">Link #2</a>
    </li>
    <li>
                <img class="icons_folder-png" src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" />
            <a href="#">Link #3</a>
    </li>
</ul>

We have got a css file with the name lowCompat.css. It contains the css classes which is needed for the images, and we also have a base64 encoded string for the src attribute, which shows a transparent 1x1 pixels image as a placeholder.

The difference when using sprites is that we only have a single request for all three images, instead of three separate requests. We have also got a new file, sprite0.png, which looks like this:

sprite0

These are the different images we want to show. We can now use this everywhere on the page.

But how can we modify what´s being rendered? What about if we want a jpg file with not so good quality, and with a background color?

To change the settings for the generated images, we need to create a settings.xml file, which we can add in /App_Sprites or /App_Sprites/Icons. If we add it in _App_Sprites, it will be used for all folders. To test this, we add the following xml to settings.xml:

<?xml version="1.0" encoding="utf-8" ?>
<ImageOptimizationSettings>
  <FileFormat>jpg</FileFormat>
  <Base64Encoding>false</Base64Encoding>
  <Quality>20</Quality>
  <BackgroundColor>ff00ff00</BackgroundColor>
</ImageOptimizationSettings>

We change the file format to jpg, change the quality to 20 (0-100 where 100 means best quality), and also change the background color to ff00ff00, which is green. The color is ARGB, which means 0000ff00 would make it transparent.

If we update the page, we get this:

sprite1

We got bad quality, but much smaller file size. With the standard settings it was 15 KB, but now it´s only 2 KB. The best thing to do here is to lower the quality as much as possible, without getting too bad quality.

We can also use this new functionality using ASP.NET Web Forms and ASP.NET Web Pages. If you use Web Forms, it includes a new ImageSprite control, which inherits the original Image control.

9 Comments

Comments have been disabled for this content.