W3C home > Mailing lists > Public > www-style@w3.org > May 2009

Sprites (was: Background position)

From: Jorrit Vermeiren <mercator+w3c@gmail.com>
Date: Mon, 18 May 2009 23:57:53 +0200
Message-ID: <bd6e15d00905181457y7905f16bw89d76b55bbfa7007@mail.gmail.com>
To: Sophie <sophie.gousset@laposte.net>, Henrik Hansen <henrikb4@gmail.com>
Cc: www-style@w3.org
On Mon, May 18, 2009 at 12:16, Henrik Hansen <henrikb4@gmail.com> wrote:
> Correct me if I'm wrong, but didn't we discuss this recently. If so what was
> the conclusion.
>> On Sun, May 17, 2009 at 22:18, Sophie <sophie.gousset@laposte.net> wrote:
>>> Hello,
>>> I have searched the archives of the list but didn’t find mention of
>>> this. Is there a possibility of allowing the definition of background
>>> position coordinates separately?
>>> This would be useful in reducing css declarations when using sprite
>>> background images.

If it hasn't come up since in the mean time (I haven't paid much
attention lately), this last came up in January, starting off in
... and continuing in January:

I don't think there was any conclusion, except that we need a better
way to deal with sprites.

And since this comes up in relation to sprites again... I've had a bit
of a think about it since that last discussion and I don't think I'm a
fan of any of the sprite() (or equivalent) notations mentioned or
linked to back then (even less so than I last stated [1]).

The reason Sophie [2] and Jethro [3] are asking for
background-position-x and -y properties is, I believe, because
currently the CSS required for sprites is rather more verbose than
necessary, especially when a single image contains a lot of sprites,
and requires a lot of work to update when a sprite image changes, even
only slightly. As much as a sprite() function would allow sprites to
be used universally, rather than just for background images, the
notation would become even more verbose (try doing Jethro's fairly
simple example [3] using any of those proposed sprite() notations).

Even if the <url> parameter to the sprite() function would become
optional, all coordinates would still need to be mentioned. I don't
know to what extent those could really be made optional.

[1] http://lists.w3.org/Archives/Public/www-style/2009Jan/0284.html
[2] http://lists.w3.org/Archives/Public/www-style/2009May/0141.html
[3] http://lists.w3.org/Archives/Public/www-style/2008Nov/0279.html

I propose the introduction of an @sprite rule, which can be used to
define the sprite matrix of a single image:

@sprite <id> {
    sprite-image: <image>;
    sprite-offsets-x: <number>+;
    sprite-offsets-y: <number>+;

Sprites can then be used as follows:
sprite(<id>, <x-index>, <y-index>)

The sprite-offsets-x and -y properties would be pixel offsets (no unit
required, I presume, though I'm not sure how or if this would work
with vector images) from the top-left corner of the image, defining
the left and top edges, respectively, of each image in the sprite.


@sprite example {
    sprite-image: url(foo.png);
    sprite-offsets-x: 0 10 20 30;
    sprite-offsets-y: 0 10 20;

If foo.png were a 40x30 pixel image, the above would define a 4x3 grid
of 10x10 pixel sprites.

In the rest of the CSS these sprites could be referred to by their x
and y indices. E.g. sprite(example, 0, 1) defines the sprite in the
first column and second row of foo.png's grid.

Note that I would like to see this as an *addition* to one of the
earlier sprite() notations. So you could, for example, still also do:
sprite(url(foo.png), 0, 10, 10, 20) or so to get the same result in
case your sprite isn't as complicated and doesn't require a special

Most sprites I know of, and all sprites I've used myself fit within a
simple, two-dimensional grid like this.

But note also that I said <image> in the sprite-image property, and
not <url>. That would allow sprite rules to be nested (presuming both
url() and sprite() would qualify as <image>), so you can refer back to
an earlier defined sprite for more complex sprites. One example I know
of that uses a sprite consisting of more than a simple grid is the
Google sprite: http://www.google.com/images/nav_logo4.png

Turning to Jethro's example again, using this @sprite rule would
result in the following:

@sprite tabs {
    sprite-image: url(tabs_sprite.png);
    sprite-offsets-x: 0 122 244 366;
    sprite-offsets-y: 0 41 82;

#tabs li a { background-image: sprite(tabs, 0, 0); }
li#slide_2 a { background-image: sprite(tabs, 1, 0); }
li#slide_3 a { background-image: sprite(tabs, 2, 0); }
li#slide_4 a { background-image: sprite(tabs, 3, 0); }
li#slide_1.current a { background-image: sprite(tabs, 0, 1); }
li#slide_2.current a { background-image: sprite(tabs, 1, 1); }
li#slide_3.current a { background-image: sprite(tabs, 2, 1); }
li#slide_4.current a { background-image: sprite(tabs, 3, 1); }
li#slide_1 a:hover { background-image: sprite(tabs, 0, 2); }
li#slide_2 a:hover { background-image: sprite(tabs, 1, 2); }
li#slide_3 a:hover { background-image: sprite(tabs, 2, 2); }
li#slide_4 a:hover { background-image: sprite(tabs, 3, 2); }

This doesn't actually simplify it nearly as much as using
background-position-x and -y would, but compared to the current
situation or one of the earlier sprite() proposals, it reduces the
complexity considerably, because the image source and sprite
coordinates need only be mentioned once: in the at-rule. So for
example, if those tabs are redesigned and the sprites change
dimension, only the at-rule would need to be updated.

Received on Monday, 18 May 2009 21:58:29 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 11 February 2015 12:34:26 UTC