Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change.Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.

Page tools

Advances in HTML5 and CSS (for example transitions, animations, transforms, text shadows, box-shadows, gradients, SVG) have improved the graphical and interactive richness of HTML. SVG filter effects are now moving to Filter Effects 1.0 to become available in CSS and HTML, in addition to SVG, and will bring effects such as grayscale, sepia tone, or hue-rotate to all web content.

Adobe proposed the CSS shaders proposal to the W3C FX task force in October 2011 and the proposed feature is now part of the CSS Filter Effect draft. This article uses the syntax of the latest CSS Filter effects draft. CSS shaders define a filter effects extensibility mechanism and provide rich, easily animated visual effects to all HTML5 content. They work particularly well with CSS animations and CSS transitions.

The following videos show examples of CSS shaders in action on HTML content.

This article describes what CSS shaders are and how they work, and includes code examples. It also covers how to use shaders to create custom effects and how to write your own custom shaders.

A few caveats: This is a work in progress. As we continue the discussion with the broader community, we will be making some changes. The syntax used in this article reflects the CSS shader's proposed syntax, but it will likely evolve as the discussions in the W3C FX Task Force and with the broader community continue. Note also that, in accordance with common practice, all the new proposed properties are prefixed with -webkit- in our WebKit prototype. For the sake of simplicity, I have omitted this prefix in the rest of the article.

Filter Effects 1.0

To understand CSS shaders, it is necessary to have a basic understanding of predefined filter effects. The following demo shows a simple filter effects example: on hover, a user gets a simple grayscale to color fade effect.

Using filter effects is pretty straightforward: the filter property defines the filter (or chain of filters) that should be applied. As you can see, it is also very easy to integrate it with CSS transitions. The filter property is animatable.

In the example, the grayscale() filter function is animated to gradually fade out because the amount parameter in the filter function is animated from 1 (full grayscale) to 0 (no grayscale) when the user hovers on the shaded element.

The W3C Filter Effects 1.0 draft specification defines two things:

A general syntax for defining a filter by assembling filter primitives in a graph.

A CSS filter property that can reference a filter definition or use one or more filter functions.

The filter property can use a number of predefined filter functions: blur, drop-shadow, gamma, grayscale, hue-rotate, invert, opacity, saturate, sepia, and sharpen. Figure 2 illustrates the effect of each:

blur(5, 5)

drop-shadow(10, 5, 5)

hue-rotate(328deg)

saturate(5)

invert(1)

grayscale(1)

opacity(0.5)

gamma(1.1, 3.6, 0)

sepia(0.5)

Figure 2. The filter effects functions.

The beauty of Filter Effects is the simplicity of the syntax and the integration with CSS animations and CSS transitions.

However, some things are more difficult. For example, what if you want to have only a portion of the element turn to gray scale? Or what if you want the transition to happen differently, for example, as a swipe effect over the element? Or what if you want a filter effect that is not amongst the predefined set of filter functions or the default set of filter primitives? This is where CSS shaders come in.

The CSS shaders proposal offers to add a custom() filter function to Filter Effects that integrates with predefined filters and CSS animations and transitions. CSS shaders provide the flexibility and expressivity needed to create arbitrary effects—from the simplest ones to the most complex.

Custom filter effects with CSS shaders

I'll start with an example. The effect shown above (fading from grayscale to color) is nice, but it can be improved. The following video shows a more sophisticated effect: when transitioning from grayscale to color, the content "wobbles" for a short while and, simultaneously, a color-swipe goes across the content, bottom to top.

This demo uses a vertex shader for the wobble effect and a pixel shader for the color swipe effect. Both are simply referenced by the custom() filter function which also carries parameters for the shaders, as well as some configuration options. Here is the code:

Note how similar the code is to the earlier grayscale example. As for other filter effects, we use the filter property to define the effect. The difference is that instead of using one of the predefined filter functions, we use the custom() function and reference the two shaders. The specifics of shaders are discussed in more detail later on. For the time being, the important thing to understand is that each shader provides a specific effect and exposes parameters that can be set and animated from CSS.

In this example, the custom filter uses a wobble.vs vertex shader (for the distortion) and the color-swipe.fs fragment shader (for the grayscale to color swipe effect).

What are shaders?

Shaders are common in 3D graphics. They are (typically) small programs that process the vertices of 3D geometry (vertex shaders) and the color of pixels (fragment shaders).

For example, a vertex shader can create a waving flag effect on a surface, or a wobble effect, as in the previous example. A fragment shader (also called pixel shader) can make arbitrary computations to determine a pixel's color. CSS shaders harness the power of hardware-accelerated shader programs.

How do CSS shaders work?

With CSS shaders, you can turn your HTML or SVG element into a vertex mesh. This is illustrated in Figure 3, as step 1. That mesh is then processed by a vertex shader (in step 2) which makes any kinds of distortion, in 3D space, possible. In step 3, the mesh is rendered (or rasterized) into pixels which the fragment shader colors.

Figure 3. The CSS shaders processing model.

As author, you can control the mesh's granularity, and you can specify parameters that control the shaders.

In the example, the element with the shaded id has its filter property set to:

Again, remember the meaning of the parameters is shader specific. In this example, the author of the shader has designed it so that at amount 0.5, the wobble has its maximum effect, and it settles back to stillness at amount 1.0. The color-swipe shader is such that between amount 0.0 and amount 1.0 it creates a bottom to top color swipe along with a shine effect, done by adding white to the pixel values at the same location as the swipe's horizontal divide. Watching the above video is the best way to understand the visual effect.

As with the grayscale filter effect earlier, the integration with CSS transition makes it very easy to set the effect in motion and is done the same way, using the transition property.

Writing shaders

In practice, it seems likely many people will use great custom effects provided by shaders that will expose easily configured parameters, as in the previous example.

Writing shaders, while taking some practice is not that difficult. Also, and this is a little known secret, they are a lot of fun to author.

Shaders are written in the OpenGL ES shading language, the same language used for WebGL shaders. Here is the vertex shader example that creates the wobble effect from the previous example.

For those not familiar with shaders, the following terminology definitions should help read the examples:

Vertex: A coordinate on the geometry processed by the shaders.

Texture: A raster image (offscreen image). CSS shaders turn an element's rendering into a texture that is used and processed by the vertex and fragment shaders.

Attributes: Per-vertex parameters, passed to the vertex shader

Uniform: Global parameters that have the same value for all vertices and pixels. They are passed from the custom() function to the shaders.

Projection Matrix: A matrix converting coordinates from the normalized vertex coordinate range ([-0.5, +0.5] along each axis) back to the actual viewport coordinate system. Typically used in the vertex shader.

Note: There are some differences in the way fragment shaders compute pixel color values in CSS Shaders due to the security constraints.

There are many good resources on the Web to learn how to write shaders or some libraries that contain excellent sets of shaders (see references at the end).

Shading languages, such as the OpenGL ES shading language, are designed to make programming visual effects easy. CSS shaders offer a way to tie this expressivity into the CSS syntax and make it easy to use and animate these effects.

Comparison with WebGL

WebGL provides an implementation for the HTML5 canvas element. WebGL offers a 3D context for canvas and, within that context, pixel shaders are available (and so are vertex shaders and all the other 3D features WebGL has to offer). WebGL operates within the bounds of the canvas for which it provides a context.

By contrast, CSS shaders provide a way to apply arbitrary shaders to arbitrary Web content.

Where to go from here

Adobe is bringing CSS shaders to the W3C as part of the FX task force and our goal is to start contributing this code to WebKit as soon as the work is accepted by W3C so that web developers can start enjoying this powerful new set of filter effects soon.

In the meantime, you may want to refer to the following resources to learn more about CSS animations and effects: