How To Create Gradients in SVG

In the previous posts, you have learned about filling an object with a solid color, you can also fill SVG shapes and objects with a gradient smooth color transitions along a vector from one shade to another instead of solid color. SVG provides two types of gradients, gradients filled on an object can be linear, where the color transition occurs along a straight line, or radial, where the transition occurs along a circular path.

Once you have defined gradients along with their unique 'id' attribute, then it is referenced using 'fill' or 'stroke' properties on a given SVG graphics element to indicate that the given element shall be filled or stroked with the referenced gradient.


LinearGradient


A linear gradient is a transition through a series of colors along a straight line. You can specify the colors you want at specific locations, called gradient stops where the stops are part of the structure of the gradient and the colors are part of the presentation. You can specify color using stop-color on style and position of the stop using offset attribute.

The offset attribute is used either a <number>, usually ranging from 0 to 1 or a <percentage>, usually ranging from 0% to 100%, which indicates where the gradient stop is placed. For linear gradients, the offset attribute represents a location along the gradient vector.

Simple two-color gradient

Here is an example to show the simple two-color gradient that fills a rectangle with a smooth transition from red to blue.
<svg width="250" height="150">
<defs>
<linearGradient id="two_color">
<stop offset="0%" style="stop-color: #ff0000;"/>
<stop offset="100%" style="stop-color: #0000ff;"/>
</linearGradient>
</defs>
<rect width="250" height="150"
style="stroke-width:2;stroke:blue;fill:none;"/>
<rect x="20" y="20" width="210" height="110"
style="fill: url(#two_color); stroke: blue;"/>
</svg>

Three-color gradient

Similar to filling with two color gradient, you can make gradient with three color stops simply adding another stop point with specifying offset point at middle. Here is an example to show the simple three-color gradient that fills a rectangle with a smooth transition from red to green then green to blue.
<svg width="250" height="150">
<defs>
<linearGradient id="three_color">
<stop offset="0%" style="stop-color: #ff0000;"/>
<stop offset="33.3%" style="stop-color: #00ff00"/>
<stop offset="100%" style="stop-color: #0000ff;"/>
</linearGradient>
</defs>
<rect width="250" height="150"
style="stroke-width:2;stroke:blue;fill:none;"/>
<rect x="20" y="20" width="210" height="110"
style="fill: url(#three_color); stroke: blue;"/>
</svg>

Defining vectors for a linear gradient

In the previous examples, you have learned to fill an object with simple two or three color linear gradients. You can also define another linear gradient with defining custom starting and ending point called gradient units using previously defined linear gradients.

Gradient units (x1, y1, x2, y2) define a gradient vector for the linear gradient. This gradient vector provides starting and ending points onto which the gradient stops are mapped. The values of x1, y1, x2, y2 can be either numbers or percentages.

URI reference 'xlink:href = <uri>' reference to a different 'linearGradient' or 'radialGradient' element within the current SVG document fragment. Any 'linearGradient' attributes which are defined on the referenced element which are not defined on this element are inherited by this element.

In the following example vectors for a linearGradient are defined using gradient units and URI reference.
<svg width="300" height="220">
<defs>
<linearGradient id="three_stops">
<stop offset="0%" style="stop-color: #ff0000;"/>
<stop offset="33.3%" style="stop-color: #00ff00"/>
<stop offset="100%" style="stop-color: #0000ff;"/>
</linearGradient>
<linearGradient id="right_to_left" xlink:href="#three_stops"
x1="100%" y1="0%" x2="0%" y2="0%"/>
<linearGradient id="down" xlink:href="#three_stops"
x1="0%" y1="0%" x2="0%" y2="100%"/>
<linearGradient id="up" xlink:href="#three_stops"
x1="0%" y1="100%" x2="0%" y2="0%"/>
<linearGradient id="diagonal" xlink:href="#three_stops"
x1="0%" y1="0%" x2="100%" y2="100%"/>
</defs>
<rect width="300" height="220"
style="stroke-width:2;stroke:blue;fill:none;"/>
<rect x="10" y="20" width="180" height="40"
style="fill: url(#three_stops); stroke: blue;"/>
<rect x="10" y="70" width="180" height="40"
style="fill: url(#right_to_left); stroke: blue;"/>
<rect x="200" y="20" width="40" height="180"
style="fill: url(#down); stroke: blue;"/>
<rect x="250" y="20" width="40" height="180"
style="fill: url(#up); stroke: blue;"/>
<rect x="10" y="120" width="180" height="80"
style="fill: url(#diagonal); stroke: blue;"/>
</svg>

spreadMethod attribute in linear gradient

spreadMethod attribute in linear gradient indicates what happens if the gradient starts or ends inside the bounds of the target rectangle. Possible values are pad, it is the beginning and ending stop colors will be extended to the edges of the object, reflect, which says the gradient will be reflected end-to-start, start-to-end until it reaches the edges of the object being filled and repeat, which says the gradient will be repeated start-to-end until it reaches the edges of the object being filled. If the attribute is not specified, the effect is as if a value of "pad" were specified.

Following example shows the effects of spreadMethod values on a linear gradient, where leftmost square's gradient padded, the middle square's gradient repeated, and the right square's gradient reflected.
<svg width="295" height="105">
<defs>
<linearGradient id="partial"
x1="20%" y1="30%" x2="40%" y2="80%">
<stop offset="0%" style="stop-color: #ff0000;"/>
<stop offset="33.3%" style="stop-color: #00ff00"/>
<stop offset="100%" style="stop-color: #0000ff;"/>
</linearGradient>
<linearGradient id="padded"
xlink:href="#partial" spreadMethod="pad"/>
<linearGradient id="repeated"
xlink:href="#partial"spreadMethod="repeat"/>
<linearGradient id="reflected"
xlink:href="#partial" spreadMethod="reflect"/>
</defs>
<rect width="295" height="105"
style="stroke-width:2;stroke:blue;fill:none;"/>
<rect x="10" y="10" width="85" height="85"
style="fill: url(#padded); stroke: blue;"/>
<use xlink:href="#show-line" transform="translate (20,20)"/>
<rect x="105" y="10" width="85" height="85"
style="fill: url(#repeated); stroke: blue;"/>
<use xlink:href="#show-line" transform="translate (130,20)"/>
<rect x="200" y="10" width="85" height="85"
style="fill: url(#reflected); stroke: blue;"/>
</svg>


radialGradient


RadialGradient is another type of gradient you can use in SVG, where the color transition occurs along a circular path. You can create radialGradient in the similar way as a linear gradient.

While creating radialGradient, the offset attribute is used either a <number>, usually ranging from 0 to 1 or a <percentage>, usually ranging from 0% to 100%, which indicates where the gradient stop is placed. For radial gradients, it represents a percentage distance from (fx,fy) to the edge of the outermost/largest circle.

Creating radial gradient with three stops

Here is an example to show the simple three-stops gradient that fills a rectangle with a smooth transition from red to green then green to blue.
<svg width="250" height="150">
<defs>
<radialGradient id="three_stops">
<stop offset="0%" style="stop-color: #ff0000;"/>
<stop offset="50%" style="stop-color: #00ff00;"/>
<stop offset="100%" style="stop-color: #0000ff;"/>
</radialGradient>
</defs>
<rect width="250" height="150"
style="stroke-width:2;stroke:blue;fill:none;"/>
<rect x="20" y="20" width="210" height="110"
style="fill: url(#three_stops); stroke: blue;"/>
</svg>

Setting transaction limits for a radial gradient

You can set transaction limits for a radial gradient with defining a circle, where the center is the 0% stop point and the outer circumference defines the 100% stop point. You define the outer circle with the cx (center x), cy (center y), and r (radius) attributes. Values of all of these attributes are expressed in percentages of the object's bounding box. The default values for all these attributes is 50%.

Following example draws a square with a radial gradient with the zero point centered at the upper left of the square and the outer edge at the lower right.
<svg width="250" height="150">
<defs>
<radialGradient id="center_origin"
cx="0" cy="0" r="100%">
<stop offset="0%" style="stop-color: #ff0000;"/>
<stop offset="50%" style="stop-color: #00ff00;"/>
<stop offset="100%" style="stop-color: #0000ff;"/>
</radialGradient>
</defs>
<rect width="250" height="150"
style="stroke-width:2;stroke:blue;fill:none;"/>
<rect x="20" y="20" width="210" height="110"
style="fill: url(#center_origin); stroke: blue;"/>
</svg>

Setting focal point for a radial gradient

You can also set up focal point for a radial gradient using the 0% stop point, which is by default should be placed within the circle established for the 100% stop point. If it's not, the SVG viewer program will automatically move the focal point to the outer circumference of the end circle.

If you want to have the 0% stop point at some point other than the center of the limit circle, you must change the fx and fy attributes, where fx, fy define the focal point for the radial gradient. The gradient will be drawn such that the 0% gradient stop is mapped to (fx, fy). If attribute fx is not specified, fx will coincide with cx.


In the following example, the circle is centered at the origin with a radius of 100%, but the focal point is at (30%, 30%).
<svg width="250" height="150">
<defs>
<radialGradient id="focal_set"
cx="0" cy="0" fx="30%" fy="30%" r="100%">
<stop offset="0%" style="stop-color: #ff0000;"/>
<stop offset="50%" style="stop-color: #00ff00;"/>
<stop offset="100%" style="stop-color: #0000ff;"/>
</radialGradient>
</defs>
<rect width="250" height="150"
style="stroke-width:2;stroke:blue;fill:none;"/>
<rect x="20" y="20" width="210" height="110"
style="fill: url(#focal_set); stroke: blue;"/>
</svg>

spreadMethod attribute for radial gradients

SpreadMethod attribute for radial gradients indicates what happens if the gradient starts or ends inside the bounds of the object(s) being painted by the gradient. It has the same values and meanings as the spreadMethod attribute on 'linearGradient' element.

You can set the spreadMethod attribute to one of the values pad, repeat, or reflect as given on the spreadMethod attribute on 'linearGradient' element.

Following example shows the effects of spreadMethod values on a radial gradient, where the leftmost square's gradient padded, the middle square's gradient repeated, and the right square's gradient reflected.
<svg width="295" height="105">
<defs>
<radialGradient id="three_stops"
cx="0%" cy="0%" r="70%">
<stop offset="0%" style="stop-color: #ff0000;"/>
<stop offset="50%" style="stop-color: #00ff00;"/>
<stop offset="100%" style="stop-color: #0000ff;"/>
</radialGradient>
<radialGradient id="padded" xlink:href="#three_stops"
spreadMethod="pad"/>
<radialGradient id="repeated" xlink:href="#three_stops"
spreadMethod="repeat"/>
<radialGradient id="reflected" xlink:href="#three_stops"
spreadMethod="reflect"/>
</defs>
<rect width="295" height="105"
style="stroke-width:2;stroke:blue;fill:none;"/>
<rect x="10" y="10" width="85" height="85"
style="fill: url(#padded); stroke: blue;"/>
<rect x="105" y="10" width="85" height="85"
style="fill: url(#repeated); stroke: blue;"/>
<rect x="200" y="10" width="85" height="85"
style="fill: url(#reflected); stroke: blue;"/>
</svg>

Read Next: How To Create Patterns in SVG