Arieh.co.il

CSS Sprites, Mobile and Accessibility

The problem

Speed is important. Developing websites, perceived speed is even more important. As web developers, we spend a lot of time optimizing our code to run faster. Nowadays, the real bottleneck for web applications is the question How long does it take for my data to get from the client to the server?

One of the ways to help us handle this problem is to reduce the number of requests to the server. We have many ways of doing this - such as combining our JS and CSS files. A very common technique, which can be found on almost any site today, is CSS Sprites.

CSS Sprites means that we combine a lot of our images into one image, and then, with some CSS magic - we position that sprite image so that it will behave as though it was many separate ones. For example, Lets take the following menu:

There are 3 important steps for this technique:

  1. We give all the elements a background-image. We also give them some fixed dimensions.
  2. We then position that background image differently for each element. Since the element has a fixed size, this essentially crops the image, giving us the desired result.
  3. Lastly - we hide the text. This is important because we are setting a background, but we want the image to replace the text. We don't want to remove it from the code, because we want our site to be readable by anyone, even those who ignore images (eg- screen readers).

It is with that 3rd part that I had my newest challenge. You see, I've been using this technique for quite a while now, and generally, I've always considered 2 cases - either your browser renders CSS2.1 completely (IE5 and so on), or it ignores CSS all together (screen readers ignores a lot of CSS, sprites included). The above solution is perfect for both, but it neglects those in the middle. And only this week I found out that middle gray area actually exists - in the mobile world.

I use Opera Mobile to surf the web on my mobile phone. It's a great browser, and the Presto engine renders CSS perfectly. But, since browsing the web is paid per KB, I use a very common setting for mobile browsers - that tells it to ignore images. While browsing my sites, I noticed a very big issue - since the browser handles CSS, it keeps the menu text hidden, but since it doesn't display images, the menu stays empty.

Solutions

The are quite a few solutions for this. The first, is to add a non-semantic element and use the sprites on it. Then, we use Z-index to put it on top of the text:

This technique works well, because it doesn't style the text. The problem with it that since it is use to cover the text, it can't handle transparency. While fixing one of my sites I ran into that exact problem, and so I came up with a different, somewhat creative alternative img sprites.

The concept is simple - instead of positioning background images, I'll position a real image, and using the alt attribute, I can tell the agent what the image means with each separate use. The CSS simply uses good-old positioning on the image, combined with overflow:hidden on the anchors.

The result:

Conclusion

There are 2 main points to this story - the first is that we are back in the days where we can't assume anything about our users. This means that we should be very careful with the magic we use to style our pages. Usability and accessibility are still two things that should always guide us, but we should keep am eye on how a solution for one case (hiding text instead of removing it) does harm another.

The second is - how flexible CSS and HTML are. To some point, I actually like this new solution - as it doesn't hide from the user (IE - screen reader) what is actually happening on the site. It is much more straight forward.

JavaScript Reference, JavaScript Guide, JavaScript API, JS API, JS Guide, JS Reference, Learn JS, JS Documentation