Designing for Speed
Using CSS Sprites and Tactical Design Strategies to Speed Up Your Theme

We recently upgraded our intranet that we use for internal planning and communications to Drupal 6. As part of the upgrade, I wanted to redesign the interface to make it faster. From the start I wanted to push the limits of the design within the constraint that every major graphical element should come from a CSS sprite — i.e. a single image that holds all the different graphical components needed. This reduces the number of HTTP requests per page which is a major factor in perceived performance. While CSS sprites are most commonly used for things like buttons, navigation, and icons, I wanted to try something a little more daring – get nearly every graphical component in the theme including the logo, header, default user pictures, and bleeds into a single request.

While it’s actually not technically possible to achieve all design possibilities by using a single sprite, good planning allows you to get away with more than usual. You can see the main image above that gets sliced and arranged in CSS into the final theme clocks in at a modest 29k. By comparison, the standalone jquery library compressed is 15k.

The following are prerequisites for a designer who’s interested in taking this approach:

  • You need to have a strong working knowledge of CSS and HTML
  • You need to have the DOM and specific markup for implementation in mind at all times while designing
  • You need to be willing to make design decisions on the basis of performance factors

I can’t stress #1 and #2 enough. Being intimately familiar with the final medium of delivery is crucial to any designer or artist’s success and planning around the strengths of CSS and HTML and the specific markup that Drupal generates is particularly important. Here are, for example, some performance-oriented decisions that I made while approaching our design:

  • Limiting the color palette of our icons to a small set of shared colors and gradients. This allows them to appear sharper and richer when the final sprite is saved as an 8-bit indexed image to increase speed.
  • Limiting the number of bleeds, gradients, and other graphical flourishes on the site, and making the shared ones as robust and multi-purpose as possible.
  • Using a fixed-width layout with thin (780px) and wide (960px) variants rather than a fluid width theme.

The final theme in action looks like this:

The switch from dozens of images in the theme to a CSS sprite has added a noticeable zip to our team intranet. In an upcoming post, I’ll describe some of the other build decisions and tools we used to increase Drupal’s speed.

8 Comments
sprites vs. cache

Since this is an intranet page, and almost all of the client browsers probably have all the images cached (if you are setting the headers appropriately), how does this really offer any advantage? I was under the impression that the css sprite technique was only really relevant for pages where the visitors are mostly new users who don’t have anything in the cache yet.

Nathan, what you say is

Nathan, what you say is certainly true. Using a CSS sprite offers the greatest benefits for a public facing site with a lot of new visitors. However, my experience with header caches is that they are less respected by browsers than you might expect.

Also calling our site a “team intranet” though is something of a lie : ) it’s also what we use to communicate with all of our clients and other developers on projects so it gets its fair share of new users and traffic.

hawt!

hawt!

Crazy!

Wow! The additional development overhead of doing sprites is often difficult to justify, however wht you took on is VERY ambitious. I’d dare say CRAZY!

Awesome!

Did you consider or try doing it in exactly TWO sprites; one for elements with fixed height, and the other for elements with fixed width?

Hey Bevan, This is a very

Hey Bevan,

This is a very good idea! There are some issues you will run into even with this split approach. What I’ve found to be the most limiting factor is background position/alignment. For example, if you need to put a bleed or fade at the bottom of an element with variable height, you

1. need to actually have it at the bottom of your sprite to have the css background-position: bottom property work.

2. you need to make sure to have enough “clearing” room above your bleed in the sprite so that an unusually large DOM element doesn’t growing into other areas of your sprite.

Combined, this makes these types of bleeds and fades the first sign of trouble when designing — you may want to split these out into their own images, or see if the design could make use of some other visual element to take their place.

Fixed vs fluid layouts

It’s amazing what we can do now with sprites. However I have to admit that I hanve never seen a single site using a single image like you managed to do.

Bravo!

Question, why is it impossible to use a fluid layout with the single sprite approach?

Thanks Jacques, I was

Thanks Jacques, I was definitely very happy when the whole thing came together.

As for fluid layouts and CSS sprites, it is totally possible to achieve a fluid layout using this approach. But it can certainly add to the complexity and difficulty of planning. CSS sprites are based on the principle of fixed dimension (in at least 1 direction) DOM elements, so introducing elements that may have variable widths and heights can be problematic.

In fact, in a lot of these cases you will probably find yourself inserting additional DOM elements to work around the problem — for example, to round off a corner of a variable-width block you will probably need to introduce additional wrapper divs, etc.

For all these reasons, I opted to avoid a fluid layout, but I would love to see someone take on the challenge of making a design that achieves this feat as well : )

Fluid/elastic sprite designs

If the designer restricts him- or herself to not using images for rounded corners (which can be done with CSS anyway) and other more complex graphics for the main layout then a fluid or elastic design shouldn’t be much more difficult. Images for inline elements won’t necessarily need to scale, and if required could be made somewhat scalable by defining relative widths and sizing down a large export of the graphic—say a logo—such that the design can be sized up while the logo doesn’t become all ‘pixelated’ and ‘unfocused’ (the right term just escaped me).

I hope I’m making some form of sense. Thanks for the insight into 8Trees and Sprites. (: