In this articles we're going to explore the various properties of radial gradient backgrounds as implemented by the WebKit and Gecko rendering engines. Gradients can used as backgrounds, pseudo-images and image masks among other things.
The -webkit styles work already in Safari 4 and the -moz equivalents in Firefox 3.6a. As always, there are slight differences in the syntax as the CSS3 standards have not been finalised.
Important: Just as this article was completed Firefox decided to completely change their radial-gradient syntax with all kinds of bizarre new options. We're waiting for the dust to settle before updating this page. In the meantime only the WebKit examples on this page will work properly.
1. Syntax for CSS Radial Gradients
The basic syntax we will be working with is as follows:
background: -webkit-gradient( radial, , , , , from(), to() ); background: -moz-radial-gradient( , , , , from(), to() ) no-repeat;
The first point and radius define the inner circle of the gradient. Inside the specified area the from() colour will be displayed. The second point and radius define the outer circle. Outside of this area you will see the to() colour. In between these two circles the gradient will be applied.
The point and radius values can be either a percentage or a pixel measurement (in WebKit without the usual px unit appended). In Firefox the default is for the background to repeat.
In the code box below we have added a radial gradient centred around a point 500 pixels across and 25% down. The inner circle (solid blue) has a radius of 20px and the outer radius (defining the end of the gradient) has a radius of 40px:
background: -webkit-gradient( radial, 500 25%, 20, 500 25%, 40, from(blue), to(#eee) ); background: -moz-radial-gradient( 500px 25%, 20px, 500px 25%, 40px, from(blue), to(#eee) ) no-repeat;
As expected, if your browser supports it, you will see a solid blue circle with a radius of 20 pixels, surrounded by a blue-to-gray gradient extending outwards a further 20 pixels.
In the following sections we're going to modify different variables so you can see the effect they have.
2. Changing the radius of the inner circle
In the examples below we are changing the radius of the inner circle from 0 to 50 pixels in 10-pixel increments. You will see the solid portion of the gradient getting larger. When the two circles are identical, however, there is no gradient and the -webkit-gradient style is nullified and the default background colour takes over.
When the inner circle is larger (the last example) the gradient is inverted going from grey to blue instead of vice-versa. That makes sense as swapping the two circles around has the same effect as swapping the from() and to() colour settings.
background: -webkit-gradient( radial, 500 25%, 0, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 500px 25%, 0px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
background: -webkit-gradient( radial, 500 25%, 10, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 500px 25%, 10px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
background: -webkit-gradient( radial, 500 25%, 20, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 500px 25%, 20px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
background: -webkit-gradient( radial, 500 25%, 30, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 500px 25%, 30px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
background: -webkit-gradient( radial, 500 25%, 40, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 500px 25%, 40px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
background: -webkit-gradient( radial, 500 25%, 50, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 500px 25%, 50px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
If you're wondering what the yellow is doing there it's simply a background colour. The gradient takes the place of a url() statement that would include an image file. Effectively the gradient becomes an image that then sits on top of the background colour.
3. Changing the position of the inner circle
This is where it starts to get trickier. While the inner circle fits inside the outer circle there is no problem. The gradient is simply squashed on one side and stretched on the other.
It's when the edges touch or cross over that you start to see strange effects. In these cases an 'arrow' is formed using the points of intersection of the two circles and the furthest point of the inner circle. Outside of that arrow the default background is visible.
background: -webkit-gradient( radial, 490 25%, 20, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 490px 25%, 20px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
background: -webkit-gradient( radial, 480 25%, 20, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 480px 25%, 20px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
background: -webkit-gradient( radial, 470 25%, 20, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 470px 25%, 20px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
background: -webkit-gradient( radial, 460 25%, 20, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 460px 25%, 20px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
background: -webkit-gradient( radial, 450 25%, 20, 500 25%, 40, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 450px 25%, 20px, 500px 25%, 40px, from(blue), to(#eee) ) yellow no-repeat;
When the inner circle is larger than the outer, the effect is reversed, just as in the previous examples:
background: -webkit-gradient( radial, 450 25%, 40, 500 25%, 20, from(blue), to(#eee) ) yellow; background: -moz-radial-gradient( 450px 25%, 40px, 500px 25%, 20px, from(blue), to(#eee) ) yellow no-repeat;
4. Adding more colours to the gradient
As with the linear gradients it's possible to insert more colours and 'color-stop' points. A color-stop specifies a colour for the gradient to 'hit' at a given point between 0, the inner circle of the gradient (equivalent to from()), and 1, the outer circle (equivalent to to()).
Here we have a gradient that transitions from orange to white to light blue. All that is changing between each example is the point at which the first transition is completed and the second one begins:
background: -webkit-gradient( radial, 500 50%, 10, 500 50%, 80, from(orange), color-stop(0.2, #fff), to(lightblue) ); background: -moz-radial-gradient( 500px 50%, 10px, 500px 50%, 80px, from(orange), color-stop(0.2, #fff), to(lightblue) ) no-repeat;
background: -webkit-gradient( radial, 500 50%, 10, 500 50%, 80, from(orange), color-stop(0.4, #fff), to(lightblue) ); background: -moz-radial-gradient( 500px 50%, 10px, 500px 50%, 80px, from(orange), color-stop(0.4, #fff), to(lightblue) ) no-repeat;
background: -webkit-gradient( radial, 500 50%, 10, 500 50%, 80, from(orange), color-stop(0.6, #fff), to(lightblue) ); background: -moz-radial-gradient( 500px 50%, 10px, 500px 50%, 80px, from(orange), color-stop(0.6, #fff), to(lightblue) ) no-repeat;
background: -webkit-gradient( radial, 500 50%, 10, 500 50%, 80, from(orange), color-stop(0.8, #fff), to(lightblue) ); background: -moz-radial-gradient( 500px 50%, 10px, 500px 50%, 80px, from(orange), color-stop(0.8, #fff), to(lightblue) ) no-repeat;
And of course we can insert more colours:
background: -webkit-gradient( radial, 500 50%, 20, 500 50%, 100, from(red), color-stop(0.2, orange), color-stop(0.4, yellow), color-stop(0.6, green), color-stop(0.8, blue), to(#fff) ); background: -moz-radial-gradient( 500px 50%, 20px, 500px 50%, 100px, from(red), color-stop(0.2, orange), color-stop(0.4, yellow), color-stop(0.6, green), color-stop(0.8, blue), to(#fff) ) no-repeat;
One final trick which you can try out yourself. If you define two color-stops at the same point then that will become a hard edge rather than a gradient.
5. Using radial gradients as image masks
Now to something potentially more interesting for designers and developers, applying radial gradients as image masks using alpha transparency. These effects will currently work only in WebKit browsers.
no style settings | -webkit-mask-image: -webkit-gradient( radial, 50% 50%, 30, 50% 50%, 90, from(#fff), to(rgba(0,0,0,0))); | -webkit-mask-image: -webkit-gradient( radial, 50% 50%, 70, 50% 50%, 90, from(#fff), to(rgba(0,0,0,0))); |
In the above examples the from() and to() colours are not important. It's only the alpha transparency that effects the image mask properties. The radius of the outer circle has been set to half the width of the photo and the two examples show the effects of a small and a large inner circle respectively.
For the browser-impaired, here's how the image mask effect renders in Safari 4:
6. Repeating radial gradient backgrounds
In Firefox having the gradient repeat is the default behaviour. Just leave off the no-repeat instruction in the above examples and you will see the gradient pattern repeat - both outwards and inwards.
Here you can see a simple gradient with no repetition. We've offset the inner and outer circles so you can see how that effects the repeated gradient:
background: -moz-radial-gradient( 500px 50%, 10px, 460px 50%, 80px, from(orange), color-stop(0.2, #fff), to(lightblue) ) no-repeat;
and with repeat enabled:
background: -moz-radial-gradient( 500px 50%, 10px, 460px 50%, 80px, from(orange), color-stop(0.2, #fff), to(lightblue) );
For those not using Firefox 3.6a or higher, here's a snapshot:
In WebKit it's a whole different story. There doesn't seem to be an option to have the gradient continue in the same fashion as Firefox (and quite some discussion as to what is 'proper' behaviour). Instead you can create a repeating tile by setting boundaries for the gradient background, effectively creating an image tile:
background: -webkit-gradient( radial, 500 50%, 10, 500 50%, 80, from(orange), color-stop(0.2, #fff), to(lightblue) ); -webkit-background-size: 100% 33%;
The -webkit-background-size option defines a box attached to the top left of the surrounding element. In this case we've set the dimensions to be 100% of the width and 33% of the height. The contents of this box are then automatically tiled to completely fill the element, as you can see in this screenshot from Safari 4:
To make it clearer what's happening, here's an example where we tile the background gradient horizontally by setting it's width to 25%:
background: -webkit-gradient( radial, 120 50, 10, 120 50, 40, from(white), color-stop(0.1, #c93), color-stop(0.3, pink), color-stop(0.6, pink), color-stop(0.9, #c93), to(white) ); -webkit-background-size: 25% 100%;
And a preview for those not using Safari 4 or higher:
Mmmmm donuts...
No comments:
Post a Comment