CSS Image Values Module

Last updated:

I've been working lately on the Image Values module in CSS, which I am partial editor of. I've recently added or rewritten about half the spec, so I thought I'd give a quick rundown of the changes. You can always find the current draft at http://dev.w3.org/csswg/css3-images.


Gradients are still the primary purpose of Image Values in my opinion. I've both simplified and complexified gradients to help with a few things.

On the simplification front, the syntax for specifying the direction of a linear gradient is much simpler. Now you have just two choices - use an <angle> to give the direction, or specify a side or corner with keywords, like "left" or "top right", to specify where the gradient starts (it ends on the opposite side/corner). Radial gradients also simplified slightly - I dropped the <angle> from their first argument entirely, because it really wasn't very useful.

On the complexification front (or simplification, depending on how you look at it), radial gradients can now specify their size and shape with explicit lengths for their axises, rather than implicitly via size and shape keywords, if they want.

All of these changes except the "dropping angles from radial gradients" bit are designed to make it easier to interpolate between gradients. Now that linear gradients are defined completely in terms of angles (the side/corner keywords are mapped to appropriate angles as well), you can easily interpolate between any two linear gradients. Now that you can explicitly specify the size and shape of a radial gradient, you can easily interpolate between any two radial gradients as well (by converting the size/shape keywords to their equivalent explicit axis lengths).

element() function

Based on the -moz-element() proposal from Mozilla, the element() function lets you use any element in the page as an image, using it in background-image and such. You can refer to elements by their id, or by assigning them a special reference value via the document.cssElementMap property.

image() function

I didn't actually author this (Elika, the other editor, did), but I'll mention it anyway. image() actually combines several different functionalities together.

The first is that of image fallback. You can specify several images, and the browser will use the first one that isn't broken (returns a 404, for instance) and is in a format it can support.

The second is resolution control. You can specify a particular resolution you want to render the image at. This is useful, for instance, for using high-resolution images, since by default CSS makes each image pixel the size of a CSS px.

The third is an accidental effect, but one that I find useful - you can treat colors as images. The final argument to the image() function can be one of the browser-generated images or a color, so you can have a final fallback in case none of the images work. Since image() is used, you know, as an image, then using a color has to return an image. You can just say something like image(blue) to get an image that is blue everywhere and has no intrinsic dimensions.

cross-fade() function

I introduced this function to help with interpolating images, so that you can, for example, use CSS Transitions on the background-image property. It takes two images and a percentage, and generates a new image that is a blend of the two source images, weighting each according to the percentage (0% is all the first image, 100% is all the second image, etc.).

Beyond just using it for representing intermediate forms when transitioning images, cross-fade() can be used for some interesting effects. For example, you can tint a picture with color by crossfading it with a color image, like cross-fade(<image>, image(blue), 20%). Or you can subtly highlight a section of an image by crossfading it with a radial gradient.

Interpolating and Serializing

Simon Fraser and Anne van Kesteren have pestered me about specifying exactly how the new values should be transitioned and serialized, respectively, for use in Transitions and Animations or the CSSOM. I've added sections which specify these details precisely. Future drafts should follow suit, especially ones that I edit.

Soon to Come

I'll be adding new functions for repeating gradients shortly. Mozilla has them in their experimental implementation, and I was just waiting for a decent use-case before adding them. Someone finally gave me one, so in they go. (The use-case was charts - bar charts, for example, are commonly styled by making some of the bars solid colors and other patterned. The most common pattern is simple diagonal stripes, which are perfectly addressed by repeating linear gradients.)

I've also been convinced of the usefulness of a few other features like running transforms on images, but it would be somewhat clumsy to continue adding them via functions. Nobody wants to see an image made out of four nested function calls. (Rotating a crossfade between a list of image fallbacks and a gradient, with some of the gradient's color-stops specified with rgba().)

So, I'll bite the bullet and adopt a suggestion made by Sylvain from MS to create an image-defining @-rule, which can take various properties like width/height, transform, opacity, etc. It'll probably also do things like having its own 'repeat' property, similar to background-repeat, which can be aware of transforms and modify the tiling grid appropriately. This way you can compose a bunch of operations together in a clear way, and then refer to the image later via some short name. This also makes things more flexible for experimentation - having one unknown property won't kill the entire @-rule, unlike one unknown function in a big nested stack.

Finally, I may also bite the bullet and add a gradient @-rule, so you can specify long or complex gradients in one place and then refer to them elsewhere by a short name. This also opens the door for further complexity, like specifying transition functions for between color-stops.

(a limited set of Markdown is supported)