How To Apply SVG Radial Gradients To A Fill Or Stroke

Like patterns, gradients can add depth and interest to a composition. Despite the current trend toward a flatter design aesthetic, gradients are still highly useful.

Last week I walked you through working with linear gradients in SVG. I promised I’d talk about radial gradients today. As you probably expect, radial gradients are similar to linear gradients in a number of ways. They mainly differ in how the gradient itself is defined.

SVG Radial Gradients

As I mentioned last week, if you understood how linear gradients work, I don’t think you’ll have any difficulty understanding radial gradients.

You define a radial gradient with the <radialGradient> element and its associated attributes. As I did last week with linear gradients, let’s start with a simple example and build from there.

1
2
3
4
5
6
7
8
9
10
<svg width="660" height="330">
 <defs>
   <radialGradient id="radial" fx="50%" fy="50%" cx="50%" cy="50%" r="75%">
     <stop offset="0%"   stop-color="#05a" stop-opacity="1"/>
     <stop offset="100%" stop-color="#0a5" stop-opacity="1" />
   </radialGradient>
 </defs>

 <rect x="0" y="0" width="600" height="300" fill="url(#radial)" />
</svg>

If you followed last week’s linear gradients examples this example should look familiar. The gradient is defined inside <defs> and gets an id of radial, which is referenced by the rectangle.

Inside the <radialGradient> element are two color stops, one blue and one green. Both are defined by <stop> elements. We saw the three attributes on the <stop> element last week and they work the same way here.

  • offset — For radial gradients it represents a percentage distance from (fx,fy) to the edge of the outermost (or largest) circle. It defines where the gradient stop is located. You can set it as a number between 0 and 1 or a percent from 0% to 100%.
  • stop-color — defines the color at the offset.
  • stop-opacitydefines the opacity of the stop color at its offset as a number between 0 and 1 or as a percent between 0% and 100%.

Let’s take a look at the resulting graphic and then I’ll talk about the attributes on the <radialGradient> element.

The gradient radiates from blue at the center of the rectangle to green at its edges, which I’m guessing is what you expected. Let’s consider how it was created.

In addition to an id of radial, I added five attributes , fx, fy, cx, cy, and r, to the <radialGradient> element.

  • r — sets the radius of a circle.
  • cx and cy — define the center of the gradient. By altering values you can move the whole gradient.
  • fx and fy — define the focal point of the gradient. By altering values you can move the point where the gradient is filled with it’s first color stop.

I’m sure you understand how the radius works, but I think some examples will help make cx, cy, and fx, fy easier to see and give you a better idea of the effects of changing any of the values.

Here I changed the radius from the previous example to 75% and left everything else the same.

1
<radialGradient id="radial" fx="50%" fy="50%" cx="50%" cy="50%" r="75%">

You can see the blue spreads further before becoming green.

Next I set the radius back to 50% and changed cx to 20%.

1
<radialGradient id="radial" fx="50%" fy="50%" cx="20%" cy="50%" r="50%">

You can see the amount of blue is the same as the first example, but the center of the gradient has moved to the left so it’s 20% from the left edge. Notice though, the highest concentration of blue is still at the center of the rectangle.

Finally, here both radius and cx are back at 50% and I changed fx to 20%.

1
<radialGradient id="radial" fx="20%" fy="50%" cx="50%" cy="50%" r="50%">

At first glance this example might look the same as the previous one, with the blue of the gradient shifted left. However notice where the highest concentration of blue is now located. It’s no longer in the center and is now 20% from the left edge of the rectangle. The focal point of the gradient has moved.

The attributes cx and cy define where the center of the gradient is located. The attributes fx and fy define where the focus of the gradient is located. By default all are at 50% so they appear to be the same, but cx and cy control different aspects of the gradient than fx and fy do.

While I’ve only changed the x components of c and f, the y component works the same way other than shifting things vertically as opposed to horizontally.

Attributes of the <radialGradient> Element

Like linear gradients there are more attributes you can add to radial gradients. In fact, the remaining attributes you can add are the exact same attributes you can add to linear gradients.

The xlink:href attribute provides a way to reference one gradient inside another. The attributes of the referenced gradient are inherited, but can be overwritten.

The gradientUnits attribute determines whether or not the cx, cy, fx, fy, and r values of the gradient scale with the shape that references them and it takes one of two values that are probably familiar to you by this point in the series.

  • userSpaceOnUse — cx, cy, fx, fy, and r represent coordinates in the current user coordinate system. In other words the values in the gradient are absolute values and don’t scale.
  • objectBoundingBox — cx, cy, fx, fy, and r represent coordinates in a system established by the bounding box of the element to which the gradient is applied. In other words the gradient scales with the element it’s being applied to.

You can also transform radial gradients using the gradientTransform attribute.

In the following example I added gradientUnits=“userSpaceOnline” to the first gradient (radial–1), which will cause the gradient to scale.

I also added a second <radialGradient> with an id of radial–2. It references #radial–1 inside an xlink:href attribute and overrides the fx value changing it to 20%. Finally I added a gradientTransform to rotate the gradient –20 degrees.

1
2
3
4
5
6
7
8
9
10
11
<svg width="660" height="330">
 <defs>
   <radialGradient id="radial-1" fx="50%" fy="50%" cx="50%" cy="50%" r="50%" gradientUnits="objectBoundingBox">
     <stop offset="0%"   stop-color="#05a" stop-opacity="1"/>
     <stop offset="100%" stop-color="#0a5" stop-opacity="1" />
   </radialGradient>
  <radialGradient id="radial-2" fx="20%" fy="50%" cx="50%" cy="50%" r="50%" xlink:href="#radial-1" gradientTransform="rotate(20)">
  </defs>

<rect x="0" y="0" width="600" height="200" fill="url(#radial-2)" />
</svg>

Hopefully that isn’t too many changes at once. The second gradient just shifts the focal point of the original gradient and then rotates it. Here’s the result.

Again some of these changes can be hard to see with radial gradients, but hopefully you can tell that the focal point has shifted to the left and that the entire gradient has been rotated.

The last attribute, spreadMethod also works the same as it did for linear gradients. It can take any of three values, pad, reflect, and repeat, and it defines how the gradient starts and ends when the values cx, and cy are inside 0% and 100%.

  • pad — (default) uses the start and end colors of the gradient to fill the remainder of the region.
  • reflect — reflects the gradient pattern start-to-end then end-to-start then start-to-end, continuously until the region is filled.
  • repeat — repeats the gradient pattern from start-to-end continuously until the region is filled.

As with linear gradients, I think all three values are easier to see with examples. Also like linear gradients the reflect and repeat values don’t work in all browsers. I’m including screenshots of them working along with the inline SVG in case the code doesn’t work in your browser.

Here’s the original example in this post again with a couple of changes. First I set the radius to 20%, because a smaller radius will make the three values of spreadMethod easier to see. Second I added the spreadMethod attribute.

1
2
3
4
5
6
7
8
9
10
<svg width="660" height="330">
  <defs>
    <radialGradient id="radial" fx="50%" fy="50%" cx="50%" cy="50%" r="20%" spreadMethod="pad">
      <stop offset="0%"   stop-color="#05a" />
      <stop offset="100%" stop-color="#0a5" />
    </radialGradient>
  </defs>

  <rect x="0" y="0" width="600" height="300" fill="url(#radial)" />
</svg>

Here’s the resulting gradient when the spreadMethod is set to pad. When the gradient reached 20% in any direction, it becomes entirely green until it reaches the edges of the rectangle

Here’s the graphic again with spreadMethod set to reflect. The gradient transitions from the blue to the green that are set on the color stops and it’s then reflected back from green to blue. Then it’s reflected again from blue to green. This pattern continues until the gradient reaches the edges of the rectangle.

SVG

Screenshot

title

Finally here’s the result when spreadMethod is set to repeat. This time the pattern repeats from blue to green. When it reaches green it changes abruptly to blue and then transitions to green again. The pattern repeats continuously until it reaches the edges of the rectangle.

SVG

Screenshot

title

Despite reflect and repeat being very similar, notice how different the results are for each value. Again this should all be familiar if you read last week’s article about linear gradients, though I think reflect and repeat look more interesting on radial gradients than linear gradients, though again you may not want to use them given the lack of full browser support.

Closing Thoughts

Gradients are the third type of fill or stroke (solid colors and patterns being the first two) we’ve seen that you can add to SVG elements.

You can create either linear (<linearGradient>) or radial (<radialGradient>) gradients and aside from the gradient itself, both elements work the same way. You define as many color stops as you’d like and you can scale or transform gradients and have one gradient refer to another to inherit its values.

With radial gradients you set a radius and locations for the center and focus of the gradient. Once you’ve played around with the values and understand what each controls, radial gradients, like linear gradients, are fairly easy to work with.

As I often suggest, the best way to learn to work with both linear and radial gradients is to copy the examples I’ve provided or any other you find and then play around with the different values, isolating one at a time for change.

The difference between cx, cy and fx, fy will probably cause the most confusion, if you have any. You’ll also find smaller values for the radius of the gradient make it easier to see the differences in the spreadMethod values.

We’ve now been looking at SVG for two and a half months so I think it’s time to move on to another topic. If you want more SVG don’t worry. I have plenty more topics to cover and I’ll get to them later in the year.

Download a free sample from my book, Design Fundamentals.

Leave a Reply

Your email address will not be published. Required fields are marked *