Thursday, December 11th, 2008

CSS Spriting without background-image

Category: CSS

Jennifer Semter has published an article on CSS spriting, and a cross-browser technique that uses divs, anchors, and clipping to get the same effect as background image clipping. The reason for the new technique is due to the issues with the current approach:

  1. You can’t attach alternate text to divs for accessibility purposes
  2. CSS Spriting and the IE6 PNG fix are incompatible
  3. The images will not print out on printouts unless the client option to print background images is selected (this is bad for logos and menus, etc)
  4. For images in pages (that are not actually background images), it seems semantically bad to hide the image in CSS.

And example code shows how it works:

  1. .menu-about { width: 106px; height: 29px; position: relative; top: 0; left: -293px; }
  2. .menu-about img { position: absolute; clip: rect(0 399px 29px 293px); }
  1. <div class="menu-about">
  2.      <img class=”transparent_png” src=”http://www.jennifersemtner.com/wp-content/uploads/2008/12/company-menu.png” alt=”About” title=About Uswidth=611? height=39? />
  3. </div>

Posted by Dion Almaer at 11:55 am
22 Comments

+++--
3.5 rating from 44 votes

22 Comments »

Comments feed TrackBack URI

JSemtner is the f’in bomb, I think I just creamed my jeans

Comment by rogersm0 — December 11, 2008

This is interesting for more than just the stated IE6 PNG Fix.

There is a bug in IE 7 and 8 that causes partially transparent pixels to be rendered as black pixels in any alpha transparent PNG that is used as a background that is shown via animation. (i.e., fade-in)

Yeah, that is a mouthful. Here is an example for those that haven’t seen it:

http://flowz.com/screens/ie7png-problem.png

Pay close attention to the buttons over the thumbnail. The current fix I used is to stop all animation for IE users. Jennifer’s technique gets around that. Thank’s Jennifer!

Comment by digerata — December 11, 2008

I think beyond visuals a more interesting challenge with CSS sprites is they don’t actually respect caching properly. Even if you put tremendously long expires times on CSS backgrounds modern browsers we test will continually send 304 requests on them. In some of these Ajax style applications there are many sprites and this round-tripping turns into significant delay. This is a known issue but is seems as if people like to ignore it as on numerous messages boards but try it yourself it is a problem at least in Firefox and IE. Of course to be fair the request reduction in general may be a big enough benefit but frankly it would be nice if you could just get your requests down to a few base files and then cache those dependent ones for a long time with no 304 requests. Just saying…

Comment by ThomasAPowell — December 11, 2008

I think in terms of semantics that solution is LESS semantic that traditional spriting. How is that image more semantic than say
About
and then hiding the text with text-indent: -999em and applying the css background sprite.

Comment by mm1982 — December 11, 2008

Very interesting indeed !!

Still, the CSS backgrounds has another advantage: if the CSS isn’t supported, the image will not appear instead of letting the whole background image (that could be quite huge) appear. Try to disable the CSS in your browser and you’ll see what I mean. On devices that don’t manage CSS, this issue is a real problem.

Comment by efattal — December 11, 2008

Well, the reason I say it’s more semantic is because if you’re displaying an image, you should call it an image. However, the CSS background technique with text-indent may be better for SEO (depending on the image/text and your targeted keywords).

Comment by jennyfofenny — December 11, 2008

That’s a good point, efattal, I’ll have to think about that one.

Comment by jennyfofenny — December 11, 2008

Back in 2000 we used to call that the Canvas-Sprites technique on http://www.Javascript-games.org. This technique has the advantage to allow sprites scaling as I documented in the technical informations of 3D TOMB II

Comment by p01 — December 11, 2008

Great idea; we’ve had a fair amount of grief on Redfin with printing when it comes to sprites, which we use pretty religiously. Somewhat interestingly, though, img tags and CSS-sprites are not orthogonal. We use img tags with a dreaded blank pixel src and then layer the sprite in as a background. Still not ideal, but the HTML is a little more semantic.

Comment by SashaA — December 11, 2008

I think you shouldn’t underestimate the overhead of the surrounding divs. The DOM should be as small as possible.

Comment by akuehner — December 11, 2008

akuehner: That’s true for the div solution (of course, it may be a good tradeoff based on analysis). However in many cases, you’ll want to use the anchor tag solution (for link functionality), and in that instance, there is no DOM bloat.

Comment by jennyfofenny — December 11, 2008

It seems that if you want to absolutely position the image anyway there’s no need for the outer div, just add the offsets to the position.

Unless I’m missing something.

Comment by tlrobinson — December 11, 2008

true jennyfofenny,

but you are displaying an image of text, thus they way I see it should really be text in the markup. I agree an image should be an image, but in that example the image as of text and so should really be text in my opinion

Comment by mm1982 — December 11, 2008

tlrobinson – the problem is that the image is full size and the clipping property clips it (without realigning the top left of the image), so it will be offset from where you might expect it. If you plan on repositioning it with the absolute property (the top and left properties), then it would be fine, but like I said, the image will be offset without it.

mm1982 – you bring up a good point. However, I think you could come up with good arguments for both sides. In my opinion, whether it’s an image of text or a regular image, it should be in an image tag with corresponding alternate text (unless the image is inconsequential – eg, a background image).

Comment by jennyfofenny — December 11, 2008

One bad thing about this technique is view the page without CSS styling. [Firefox = View –> Page Style –> No Style]
.
You get big images on the page where ever you use this technique. So if you use one big image for every graphic on your site, I will feel sorry for your users that have special needs.

Comment by epascarello — December 11, 2008

This is a cool alt css technique no doubt.

Just avoid for sites that may be used on a cellphone.

Comment by Tr0y — December 12, 2008

I don’t get why the clip method is so exciting? Once you have to nest elements to get the effect why not just set overflow: hidden on the parent?

The whole business could be done much simpler with

.menu-about { width: 106px; height: 29px; overflow: hidden; }
.menu-about img { margin-left: -293px; }

Comment by ProggerPete — December 12, 2008

ProggerPete — Good solution, maybe a better solution I think :)

Comment by RodrigoCardoso — December 12, 2008

Thanks. It is a good trick.

Comment by tajary — December 12, 2008

See to next generation of CSS Sprites based on data:URI DURIS – Data:URI [CSS] Spites .
Will soon appear description on english.

Comment by sirus — December 12, 2008

I tried using this technique earlier in the year but had to drop it as it doesn’t play well with filter:alpha(opacity=x). Shame really.

Comment by jaffathecake — December 17, 2008

You misspelled her lastname.

Comment by mawe — December 20, 2008

Leave a comment

You must be logged in to post a comment.