Sprites (was: Background position)

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
November:
http://lists.w3.org/Archives/Public/www-style/2008Nov/0279.html
... and continuing in January:
http://lists.w3.org/Archives/Public/www-style/2009Jan/0181.html

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.

E.g.

@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
at-rule.

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.


Jorrit

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