This Series
Introduction
This is part 2 of a 3 part series about
the ASP.NET CSS Sprite Generator package.
It allows you to
compress and resize the images in your
ASP.NET web site on the fly, and to combine them into sprites.
Simply add the ASP.NET CSS Sprite Generator dll and
configure the package
in your web.config - no need to change the site itself.
Contents
Part 1
Part 2
Part 3
Configuration
Configuration for the package fall in three categories:
-
Overall Configuration
- settings that apply to the package as a whole, such as whether it is active or not,
whether it processes page images, etc.
-
Image Groups
- determine which images are processed and how.
You've already come across groups in the
quick start section.
-
cssImages elements
- tell the package which CSS background images to process, and set restrictions
on how they can be combined into sprites to cater for repeating background images.
These categories are discussed in the following sections.
Overall Configuration
The package supports these package wide configuration settings:
Overall Switches
Image Gathering
Options that determine how the package finds the images to be processed
Sprite Generation
Options that determine how the package generates sprites
Overall Switches
active
Determines when the package is active. When it is not active, it doesn't affect your site at all and none of the other attributes or child elements listed in this section have any effect.
Value |
Description |
Never |
Package is never active, irrespective of debug mode |
Always |
Package is always active, irrespective of debug mode |
ReleaseModeOnly (default) |
Package is only active in Release mode |
DebugModeOnly |
Package is only active in Debug mode |
Example
<cssSpriteGenerator active="Always" >
...
</cssSpriteGenerator>
Whether your site is in Debug or Release mode depends on the debug attribute of the compilation element
in your web.config file. If that attribute is set to false, your site is in Release mode (as it should be when live).
When it is set true, it is in Debug mode (as it should be in development). It looks like this in web.config:
<configuration>
...
<system.web>
<compilation debug="true">
...
</compilation>
...
</system.web>
...
</configuration>
By default, the package is only active in Release mode - so you won't see any effect while you're developing.
To ensure that the package is active in both Release mode and in Debug mode, set active to Always, as shown in
the example above.
Note that the active property acts as a master switch for the whole package.
If it isn't active, none of the other properties have any effect.
exceptionOnMissingFile
Determines whether the package throws an exception when an image file is missing.
Value |
Description |
Never (default) |
The package never throws an exception when an image file is missing. |
Always |
The package always throws an exception when an image file is missing. |
ReleaseModeOnly |
The package only throws an exception if the site is in Release mode. |
DebugModeOnly |
The package only throws an exception if the site is in Debug mode. |
Example
<cssSpriteGenerator exceptionOnMissingFile="DebugModeOnly" ... >
...
</cssSpriteGenerator>
In order to process an image, the package has to actually read that image. What happens if the image file cannot be found on the web server?
That is determined by the exceptionOnMissingFile attribute:
- If exceptionOnMissingFile is active (see table above) and the package finds that an image file cannot be found,
it throws an exception with the path of the image. That makes it easier to find missing images.
-
If exceptionOnMissingFile is not active, the package doesn't throw an exception and recovers by
not processing the image. For example, if the image was found via a img tag, it will leave the tag alone.
If all images should be present in your development environment, than it makes sense to set exceptionOnMissingFile
to DebugModeOnly. That way, you quickly find broken images while developing your site, while preventing exceptions in
your live site where you probably prefer a broken image over an exception.
Keep in mind that if you want exceptions while the site is in Debug mode, you have to ensure that the package is actually
active in Debug mode - set active to Always to make that happen.
Image Gathering
processPageImages
Determines whether images on the current page are processed
Value |
Description |
Never |
Images on the current page are never processed |
Always (default) |
Images on the current page are always processed |
ReleaseModeOnly |
Images on the current page are processed if the site is in Release mode. |
DebugModeOnly |
Images on the current page are processed if the site is in Debug mode. |
Example
<cssSpriteGenerator processPageImages="Never" ... >
</cssSpriteGenerator>
Normally when a page on your site opens, the package finds all the img tags on the page, assigns them to
image groups and processes the groups into sprites. It then replaces the img tags
with div tags that show that part of the sprite matching the original image - so your page still looks the same but loads quicker
(details).
When you switch off processPageImages, the package no longer goes through the page looking for img tags. It also won't
replace any img tags.
You would switch processPageImages off if you only wanted to
process CSS background images.
processCssImages
Determines whether the CSS background images listed in
cssImages are processed
Value |
Description |
Never |
CSS background images are never processed |
Always (default) |
CSS background images are always processed |
ReleaseModeOnly |
CSS background images are processed if the site is in Release mode. |
DebugModeOnly |
CSS background images are processed if the site is in Debug mode. |
Example
<cssSpriteGenerator processCssImages="Never" ... >
</cssSpriteGenerator>
If this option is active (the default), than the CSS background images you've listed in
the
cssImages element
are processed by the package.
processFolderImages
Determines whether images stored in one or more folders on the web server are processed.
See the sample web site DemoSite_FolderImages in the downloaded solution.
Value |
Description |
Never (default) |
The package never processes images from folders on the web server |
Always |
The package always processes images from folders on the web server |
ReleaseModeOnly |
The package only processes images from folders on the web server if the site is in Release mode |
DebugModeOnly |
The package only processes images from folders on the web server if the site is in Debug mode |
Example
<cssSpriteGenerator processFolderImages="Always" ... >
</cssSpriteGenerator>
In addition to having the package find images on the current web page (if
processPageImages is active) and from the
cssImages element (if
processCssImages is active), you can also get it to find images
from one or more folders on the web server.
Why would you want to add images to a sprite that are not actually on the page? Take a very simple web site that uses 3 small icons on its pages, but not all icons appear on
all pages:
Page | Icons used |
default.aspx | contactus.png, cart.png, print.png |
contactus.aspx | cart.png, print.png |
cart.aspx | contactus.png, print.png |
If you had the package only read images from the current web page, than it would create different sprites for each page, because each page
has a different set of icons. However, it would be far more efficient to have all 3 icons in the one sprite. That way, when a visitor moves from
one page to the other, that single sprite is still in browser cache, so doesn't have to be loaded again over the Internet.
The way to do that is to get the package to read all icons when it creates a sprite, not just the ones that are on the current web page.
To get the package to find images
from one or more folders on the web server, set processFolderImages active. You then also need to set
imageFolderPathMatch to determine specifically which images should be
read.
Just as with images taken from the current web page and from
the cssImages elements, images taken from one or more folders are first assigned to
image groups. Only images assigned to a group can become part of a sprite.
This means that if you want to add particular images to a sprite even if they are not on the current web page and not in the
cssImages element, you have to take these steps:
-
Set processFolderImages active;
-
Make sure that the file paths of the desired images match imageFolderPathMatch;
-
Make sure that the images match a group, so they can be worked into a sprite. The images taken from folders
do not all have to match the same group.
For example, if you have a folder images\icons with .png and .gif images and you want all those images to be made into a sprite
irrespective of whether they appeared on the current page, you could use:
<!--switch on processing of images from web server folders, but only process those
that are in images\icons and that end in .png or .gif-->
<cssSpriteGenerator processFolderImages="Always"
imageFolderPathMatch="\\images\\icons\\.*?(png|gif)$" ... >
<imageGroups>
...
<!--add .png images that live in images\icons to this group-->
<add groupName="icons" filePathMatch="\\images\\icons\\.*?png$" />
<!--add .gif images that live in images\icons to this second group-->
<add groupName="icons" filePathMatch="\\images\\icons\\.*?gif$" />
</imageGroups>
</cssSpriteGenerator>
imageFolderPathMatch
If the
processFolderImages property is active, than
this property is required. It determines which image files are read.
Type |
Default |
string (regular expression) | none |
Example
<cssSpriteGenerator imageFolderPathMatch="\\images\\img1" ... >
</cssSpriteGenerator>
For details on the folder images feature, see
processFolderImages.
The imageFolderPathMatch property is a regular expression.
If processFolderImages is active, than the package
looks at the file paths of all .png, .gif and .jpg files in the root directory of the site and its subdirectories.
Those image files whose paths match imageFolderPathMatch will be processed.
For example, to process all image files in directory
images\img1, you would use:
<!--all images in images\img1-->
<cssSpriteGenerator imageFolderPathMatch="\\images\\img1\\" ... >
</cssSpriteGenerator>
(it uses double backslashes because the backslash is a special character in regular expressions, so needs to be escaped with another backslash)
If you wanted to process only the .png files in directory
images\img1, you would use:
<!--all .png images in images\img1-->
<cssSpriteGenerator imageFolderPathMatch="\\images\\img1\\.*?png$" ... >
</cssSpriteGenerator>
If you want to process all image files in the root directory of the site and its subdirectories, use:
<!--all images in the site-->
<cssSpriteGenerator imageFolderPathMatch="\\" ... >
</cssSpriteGenerator>
If your site writes images to the root directory of the site or one of its sub directories (for example if visitors can upload images),
than make sure that those images are stored in a directory that isn't matched by
imageFolderPathMatch, otherwise they could wind up in sprites. Those sprites would get bigger with every image added.
Additionally, if your site writes images frequently, such as more than once every 5 minutes, consider storing these images
outside the root directory of the site. For faster processing, the package keeps the structure of the root directory and its
sub directories in cache. Each time an image is added to the root directory or one of its sub directories,
that cache entry is removed to ensure it isn't outdated, meaning that the package has to rebuild that cache entry again.
Sprite Generation
copiedImgAttributes
Determines which attributes are copied over from an img tag when it is replaced by a div tag.
Type |
Default |
string (regular expression) | all attributes copied (except the ones listed below) |
Example
<cssSpriteGenerator copiedImgAttributes="onclick|id" ... >
</cssSpriteGenerator>
When the package replaces an img tag with a div tag, it copies over
the attributes you had included with the img (with some
exceptions, see below). For example, if you had:
<img id="..." onclick="..." onmouseout="..." ... />
That will be replaced with:
<div id="..." onclick="..." onmouseout="..." ... ></div>
Normally, this is what you want. But if it isn't, you can prevent certain attributes from being copied over
through the copiedImgAttributes property. That property is interpreted as a regular expression.
When you specify copiedImgAttributes, only those attributes that match the regular expression
will be copied over (with some
exceptions).
This means that if your img tag looks like this:
<img id="..." onclick="..." onmouseout="..." ... />
And you specified
a copiedImgAttributes
that only matches
id and onclick but not onmouseout:
<cssSpriteGenerator copiedImgAttributes="id|onclick" ... >
</cssSpriteGenerator>
Than the resulting div tag will only have the id and onclick attributes:
<div id="..." onclick="..." ... ></div>
Keep in mind that if you don't specify
copiedImgAttributes at all, all attributes (with some
exceptions) will be copied over.
Exceptions
The package gives special treatment to some attributes:
-
src is used by the img tag to load the image, but this is now done via CSS, so it is never copied over.
-
width and height are set by the package itself.
-
alt is used as the contents of the span or div tag that replaces the img tag
(details).
-
class and style are copied over. But if the package generates an additional class name than it gets added to any class attribute you already had
on the img tag
(it
will create a new class attribute if needed). Similar story with any style elements generated by the package.
inlineSpriteStyles
Determines whether the styling needed with the div tags
that replace the img tags is inline or in a separate .css file.
Value |
Description |
false | Additional styling is placed in a separate .css file |
true (default) | Additional styling is inline |
Example
<cssSpriteGenerator inlineSpriteStyles="false" ... >
</cssSpriteGenerator>
In the section about
how sprites work,
you saw how the div tags that replace your img tags use additional styling to show the correct
area of the sprite - using background, width, height, etc.
If you leave inlineSpriteStyles at true, the package inlines all the additional styling.
That gives you div tags such as this:
<div style="width: 32px; height: 32px;
background: url(/TestSite/___spritegen/2-0-0-90- ... -53.png) -200px -0px;
display:inline-block;"
></div>
However, if you set inlineSpriteStyles to false,
the additional styling is placed in a separate .css file which is generated in the same
directory as the sprite images themselves. The generated div tags will refer to the styling via CSS classes.
This gives you div tags such as this:
<div class="c0___spritegen" > </div>
In that case, make sure that the head tags of your pages have runat="server", so the package can
add a link tag for the .css file to the head section:
<head runat="server">
Here are the advantages/disadvantages of setting inlineSpriteStyles to false:
-
The advantage of using a separate .css file is that the next time the page is loaded, the .css file may still be in browser cache - so all that additional styling doesn't have
to be loaded over the Internet. This would apply if your visitors tend to hang around on your site, hitting several pages in the one visit.
-
The drawback of using a separate .css file is that if that file is not in browser cache, the browser has one more file to load.
Also, if your web server uses
compression,
the additional inlined styles don't add much to the number of bytes going over the Internet because they are highly compressible.
There are a few cases where it may make sense to place the additional CSS in a separate CSS file by
setting inlineSpriteStyles to false:
-
You're pretty sure that on many visits the separate CSS file will be in browser cache.
-
You use the
cssImages element to process CSS background images.
In that case, the package always generates a separate CSS file with styles that override existing
CSS styles to make them work with the new sprites. If you now set inlineSpriteStyles to false,
the additional CSS for the div tags will
go into the same CSS file as the CSS for the background images, rather than a separate CSS file. This means
you've reduced the size of your .aspx pages by taking out the inlined styles, without incurring an additional CSS file load.
-
You use the
Combine And Minify package to combine and minify CSS and JavaScript files on your site.
In that case, Combine And Minify can combine the separate CSS file with the other CSS files, so you don't incur the
extra CSS file load.
generatedFolder
Sets the folder where the generated .css file (if there is one) and the sprites are stored.
Type |
Default |
string | ___spritegen |
Example
<cssSpriteGenerator generatedFolder="generated\sprites" ... >
</cssSpriteGenerator>
This folder will be created (if it doesn't already exist) in the root folder of the site.
You can include one or more \ in this property. In that case, you'll get a folder and one or more subfolders.
classPostfix
Postfix used to ensure that generated class names are unique.
Type |
Default |
string | ___spritegen |
Example
<cssSpriteGenerator classPostfix="___generated" ... >
</cssSpriteGenerator>
If you set inlineSpriteStyles to false, the package generates a .css file
with the additional CSS needed to
make the sprites work. To make sure that the names of the generated CSS classes do not clash with
the other CSS classes in your site, the contents of classPostfix is appended to the generated class names.
If you find that the names of the generated CSS classes clash with the names of other CSS classes in your site,
you can change classPostfix to fix this.
Conclusion
This was part 2 of this 3 part series. In
part 3
we'll
find out about Image Groups, which allow you to manipulate your images on the fly, select images for inclusion into sprites, etc.
We'll also go into handling of CSS background images.