CSS3 radial gradients
Introduction
Gradients are much-used on web sites: if you want to liven up pretty much any UI feature (buttons, panels, headers, etc.) you can use a gradient, although you should use them sparingly to avoid the "web site christmas tree effect"™. Traditionally we used CSS background images to add gradients to our UIs, and they worked ok, but they were rather inflexible. You'd have to go to your image editor and make changes to the image file every time you wanted to change the colours, size or direction of the gradient.
The CSS Image Values and Replaced Content Module Level 3 comes to the rescue by allowing us to create gradients on elements programmatically. You can change colours, etc. with a quick chance to the code, and the gradients are so much flexible. For example, you can set colour stops at different percentages across the element you are applying it to, so in fluid layouts the gradient will adjust to fit as the element changes in size.
There are two types of gradients defined in the spec, linear gradients and radial gradients. We covered the former in a previous article — CSS3 linear gradients. This article on the other hand focuses on radial gradients. We'll go through all the basic syntax, and also look at repeating radial gradients near the end of the article.
Opera has included radial gradient support in its latest Opera 12 snapshot (see the Opera desktop team blog). Radial gradients are also supported in Safari 5.1+, Firefox 3.6+, Chrome 10+ and IE10. At the time of writing (October 2011), all browsers require a vendor prefix (for Opera, this is -o-).
Radial gradient syntax
As a recap, the syntax of linear gradients is fairly simple:
background-image: linear-gradient(top left,rgb(255,0,0),rgb(100,0,0) 50%,rgb(50,0,0) 75%,rgb(150,0,0));
Inside the brackets you first include a setting for the gradient to go in (top left means "start at the top left of the element, and travel diagonally towards the bottom right"), then you include a series of colour stops for the gradient to flow smoothly in between (you can specify these in percentages or fixed measurement units). The above line creates a gradient that looks like the following image:

Figure 1: A simple linear gradient example.
Radial gradients are a little bit more complicated, but still don't take much time to get used to. The syntax takes the following form:
radial-gradient(position,size and shape,colour stops);
So for example:
radial-gradient(50% 50%, 70% 70%, rgb(75, 75, 200), rgb(0, 0, 75))
Will create a gentle blue gradient radiating from the center of the element it is applied to, kind of like this:

Figure 2: A simple radial gradient example.
Now let's explore the three syntax areas — position, size and shape, and colour stops.
position
The position the gradient radiates from is determined by specifying the position of its centre. This takes the form of up to two keyword or unit values, specified in exactly the same way as CSS background-position. So for example (the button in the example is 107 pixels wide):
-
left topmeans "place the gradient centre in the top left corner".
-
20% 70%means "place the gradient centre 20% across the element and 70% of the way down".
-
70px 80pxmeans "place the gradient centre 70 pixels across the element and 80 pixels down".
-
0%means "place the gradient centre on the left hand edge of the element, centred vertically". If you only specify a single value, that value is taken as the horizontal value, and the vertical value is set to50%(orcenter).
-
If you set no value at all for the gradient position, it is assumed to be in the center of the element, ie
center centeror50% 50%.
size and shape
the gradient size and shape is set using zero or two values, and it can be done in two different ways — using explicit shapes, and using implicit shapes.
Explicit shapes
When using explicit shapes, the two values you set are the horizontal and vertical radii of the shape. If they are set to the same value, you will get a circle. If they are different, you will get an ellipse (oval). You can use any CSS units that would make sense in the situation. So for example:
-
40px 40pxmeans "make the gradient circular, and give it a radius of 40px".
-
20% 40%means "make the gradient an ellipse, and give it a minor radius of 20% of the element width, and a major radius of 40% of the element height".
- If you only specify one value, it will assume a circle with that radius set. So
40pxis equivalent to40px 40px - If you don't set a value at all, the setting defaults to
ellipse cover(see next section).
Note: At the time of writing, Chrome seemed to support explicit shape settings, but only for circles. Setting two different values produced a circular gradient with radius equivalent to the first of the two values. Firefox only seems to support implicit keywords (see next section). Safari has converted to using the new gradient syntax, but if you still need to use the old syntax, you can generate it using John Allsopp's Radial gradients tool.
Implicit shapes
When using implicit shapes, you use up to two values. The first value is set to circle or ellipse, to specify if you want a circle or an ellipse. The second value is set to one of a number of different values, which make the gradient span across the element in different ways (for this example we've made the button square, and set the position of the gradient centre to 35% 25%):
-
closest-sidepositions the gradient so that its edge just touches the side of the element nearest to its centre in the case of a circle, or so that its edge just touches the horizontal and vertical sides of the element nearest to its center, in the case of an ellipse. You can use the keywordcontainin place ofclosest-side— the following arecircle closest-sideandellipse closest-side:

-
closest-cornerpositions the gradient so that its edge just touches the corner of the element nearest to its centre — the following arecircle closest-cornerandellipse closest-corner:

-
farthest-sidepositions the gradient so that its edge just touches the side of the element farthest away from its centre in the case of a circle, or so that its edge just touches the horizontal and vertical sides of the element farthest way from its center, in the case of an ellipse. The following arecircle farthest-sideandellipse farthest-side:

-
farthest-cornerpositions the gradient so that its edge just touches the corner of the element farthest from its centre. You can use the keywordcoverin place offarthest-corner— the following arecircle farthest-cornerandellipse fatherest-corner:

If you don't use two values, the defaults are assumed, which are circle and cover.
Firefox doesn't support use of two keywords together, such as circle closest-side: circle is assumed, and then you have to specify a single keyword on its own, eg closest-side, or farthest-corner. Chrome seems to support all the values, but it doesn't support the ellipse values properly - it just seems to create bigger circles that fall outside the element perimeter.
Colour stops
In the last section of the radial gradient syntax, you specify at least two colour stops — these specify what colour is found in different positions along the gradient, and the browser fills in the in-between stages. You can specify the position along the gradient (starting at the centre of the gradient and going outwards) in any unit that it makes sense to (although you'll probably use percentages, pixels or ems). You can specify the colours themselves in any colour units that the browsers support (including alpha channel colours). Each colour stop is separated off using commas.
-
#ff0000, #000000: The simplest setting for colour stops is to just use two colours. When no position unit is specified, the browser assumes that the first colour is at 0% (right in the center), and the second one is at 100% (right on the edge)
-
rgb(255,0,0), rgb(150,150,150) 50%, rgb(0,0,0): Here we have three colour stops, with the colours set using RGB. The first colour is again at 0%, and the last one is at 100%, but we've also got a different color stop at 50%.
-
rgb(255,0,0) 20px, rgb(150,150,150) 40px, rgb(0,200,0) 60px, rgb(0,0,0) 80px: Four colour stops, this time positioned along the gradient using pixel values. You'll notice that if you don't position the first and last colour stops at the start and end of the gradient, the space before the first one will adopt its colour, and the space after the last one will adopt the same colour as it too.
And so on and so on. You can have as many colour stops as you like.
Looking at a real example
To show some real usage of radial gradients, let's have a look at a little button panel I whipped up: view the live example.

Figure 3: A panel of buttons — no images in sight.
Each button is a link, with block display, width and height set, border-radius set to make them round, and a simple linear gradient used to give each one depth, for example:
background-image: radial-gradient(30% 40%, rgb(255,0,0), rgb(0,0,0));
The page background was written by Divya Manian, and is composed entirely of background-image gradients — see Marrakesh for an explanation of the pattern, and see Lea Verou's excellent CSS3 patterns gallery for more inspiration.
When the buttons are focused on, they are depressed slightly. When they are clicked, they press fully in. I have achieved this by use of varying inset box shadows on hover, focus and active states.
Repeating radial gradients
In the same manner as linear gradients, you can create repeating radial gradients by using the relevant repeat property, in this case repeating-radial-gradient. This simply takes the pattern you have set for your radial gradient, and just repeats it as far as the element it is applied to extends. These examples come from my live repeating radial gradients demo:
#repeat1 {
background: repeating-radial-gradient(center, 30px 30px, #DD0000, #FF0000 50%, #DD0000);
}
#repeat2 {
background: repeating-radial-gradient(center, 30px 30px, #DD0000, #FF0000 50%);
}
#repeat3 {
background: repeating-radial-gradient(center, circle closest-side, #DD0000, #FF0000 50%, #DD0000);
}
#repeat4 {
background: repeating-radial-gradient(center, #DD0000, #FF0000 50%, #DD0000);
}

Figure 4: Repeating radial gradient examples.
Let's run through these one by one:
- The first example gradiates from one red, to a brighter red, and back again, over the course of 30 pixels. This pattern is then repeated again and again.
- The second example gradiates from one red to the other, but then stops at 50%, so the pattern isn't repeated as smoothly.
- The third example is set to
circle closest-side, so the gradient is executed over a much larger space. This means that there is only enough space to repeat the gradient about one and a half times, even in the containing element's longest dimension. - The fourth example has no size set, so the default is adopted, which fills up the whole area nicely. But this means that there is no space for repeating the gradient at all.
Summary
I hope this article has given you all you need to know to start using radial gradients on your designs! Please let us know what you think of Opera's implementation — feedback is always helpful, good or bad. You might also want to check out Gradient, a really nice little app for Mac OS X that generates cross-browser gradient code.
What you've seen here isn't the limit of uses for radial gradients. According to the spec, you can use them anywhere where you can use images, so you should experiment with using them with border-image, list-style-image, etc.
Useful links:
- Opera 12 snapshot that supports repeating gradients
- Lea Verou's fantastic CSS3 gradients gallery
- The CSS gradients working draft
This article is licensed under a Creative Commons Attribution 3.0 Unported license.
Comments
The forum archive of this article is still available on My Opera.
You must be logged in to write a comment. If you're not a registered member, please sign up.