SVG Linear and Radial Gradients
There are two types of SVG gradients: linear and radial. They are defined separately from where they are used, which promotes reusability. You must give each gradient an id attribute to allow other elements to reference it. Gradient definitions can be placed in a <defs> element or an <svg> element.
Linear Gradient
Linear gradients change along a straight line. To insert one, you create a <linearGradient> node inside the <defs> section of your SVG file.
Basic example:
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>SVG Demo</title>
<meta name="viewport" content="width=device-width" />
</head>
<body>
<svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" role="img">
<title>A gradient</title>
<linearGradient id="red-gradient">
<stop class="begin" offset="0%" stop-color="red" />
<stop class="end" offset="100%" stop-color="black" />
</linearGradient>
<linearGradient id="pink-gradient" stop-opacity="0.5">
<stop class="begin" offset="0%" stop-color="magenta" />
<stop class="end" offset="100%" stop-color="black" />
</linearGradient>
<rect x="0" y="0" width="100" height="100" fill="url(#red-gradient)" />
<circle cx="50" cy="50" r="30" fill="url(#pink-gradient)" />
</svg>
</body>
</html>
And this is how the svg element alone looks (after adding attribute width="33%"):
In the example above a linear gradient is applied to a <circular> and a <rect> element. Inside the linear gradient are several <stop> nodes. These nodes tell the gradient what color it should be at certain positions by specifying an offset attribute for the position, and a stop-color attribute.
This can be assigned directly or through CSS.
<style>
#rect1 {
fill: url("#gradient1");
}
</style>
You can insert as many stop colors as you like to create a blend that's as beautiful or hideous as you need, but the offsets should always increase from 0% (or 0 if you want to drop the % sign) to 100% (or 1). Duplicate values will use the stop that is assigned furthest down the XML tree.
Also, like with fill and stroke, you can specify a stop-opacity attribute to set the opacity at that position. The circle element is filled with a gradient with attribute stop-opacity="0.5"
To use a gradient, you have to reference it from an object's fill or stroke attribute. This is done the same way you reference elements in CSS, using a url. In this case, the url is just a reference to our gradient. To attach it, set the fill to, say, url("#gradient1"), and voilĂ ! Our object is now multicolored. You can do the same with stroke.
The <linearGradient> element also takes several other attributes, which specify the size and appearance of the gradient. The orientation of the gradient is controlled by two points, designated by the attributes x1, x2, y1, and y2. These attributes define a line along which the gradient travels. The gradient defaults to a horizontal orientation, but it can be rotated by changing these. Gradient2 in the above example is designed to create a vertical gradient.
Radial Gradients
Radial gradients are similar to linear ones but draw a gradient that radiates out from a point. To create one you add a <radialGradient> element to the <defs> section of your document.
Basic example
<?xml version="1.0" standalone="no"?>
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="RadialGradient1">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
<radialGradient id="RadialGradient2" cx="0.25" cy="0.25" r="0.25">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
</defs>
<rect
x="10"
y="10"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#RadialGradient1)" />
<rect
x="10"
y="120"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#RadialGradient2)" />
</svg>
which results in:
Like linear gradients, the <radialGradient> node can take several attributes to describe its position and orientation. However, unlike linear gradients, it's a bit more complex. The radial gradient is again defined by two points, which determine where its edges are. The first of these defines a circle around which the gradient ends. It requires a center point, designated by the cx and cy attributes, and a radius, r. Setting these three attributes will allow you to move the gradient around and change its size, as shown in the second rect[angle] above.
The second point is called the focal point and is defined by the fx and fy attributes. While the first point described where the edges of the gradient were, the focal point describes where its middle is. This is easier to see with an example</radialGradient>
<?xml version="1.0" standalone="no"?>
<svg width="120" height="120" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="Gradient" cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
</defs>
<rect
x="10"
y="10"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#Gradient)"
stroke="black"
stroke-width="2" />
<circle
cx="60"
cy="60"
r="50"
fill="transparent"
stroke="white"
stroke-width="2" />
<circle cx="35" cy="35" r="2" fill="white" stroke="white" />
<circle cx="60" cy="60" r="2" fill="white" stroke="white" />
<text x="38" y="40" fill="white" font-family="sans-serif" font-size="10pt">
(fx,fy)
</text>
<text x="63" y="63" fill="white" font-family="sans-serif" font-size="10pt">
(cx,cy)
</text>
</svg>
If the focal point is moved outside the circle described earlier, it's impossible for the gradient to be rendered correctly, so the spot will be assumed to be within the edge of the circle. If the focal point isn't given at all, it's assumed to be at the same place as the center point.
spreadMethod Attribute
Both linear and radial gradients also take a few other attributes to describe transformations they may undergo. The only other one I want to mention here is the spreadMethod attribute. This attribute controls what happens when the gradient reaches its end, but the object isn't filled yet. It can take on one of three values, "pad", "reflect", or "repeat". "pad" is what you have seen so far. When the gradient reaches its end, the final offset color is used to fill the rest of the object. "reflect" causes the gradient to continue on, but reflected in reverse, starting with the color offset at 100% and moving back to the offset at 0%, and then back up again. "repeat" also lets the gradient continue, but instead of going backwards, it just jumps back to the beginning and runs again.
<svg width="220" height="220" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient
id="GradientPad"
cx="0.5"
cy="0.5"
r="0.4"
fx="0.75"
fy="0.75"
spreadMethod="pad">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
<radialGradient
id="GradientRepeat"
cx="0.5"
cy="0.5"
r="0.4"
fx="0.75"
fy="0.75"
spreadMethod="repeat">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
<radialGradient
id="GradientReflect"
cx="0.5"
cy="0.5"
r="0.4"
fx="0.75"
fy="0.75"
spreadMethod="reflect">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="blue" />
</radialGradient>
</defs>
<rect
x="10"
y="10"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#GradientPad)" />
<rect
x="10"
y="120"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#GradientRepeat)" />
<rect
x="120"
y="120"
rx="15"
ry="15"
width="100"
height="100"
fill="url(#GradientReflect)" />
<text x="15" y="30" fill="white" font-family="sans-serif" font-size="12pt">
Pad
</text>
<text x="15" y="140" fill="white" font-family="sans-serif" font-size="12pt">
Repeat
</text>
<text x="125" y="140" fill="white" font-family="sans-serif" font-size="12pt">
Reflect
</text>
</svg>
Both gradients also have an attribute named gradientUnits, which describes the unit system you're going to use when you describe the size or orientation of the gradient. There are two possible values to use here: "userSpaceOnUse" or "objectBoundingBox". "objectBoundingBox" is the default, so that's what has been shown so far. It essentially scales the gradient to the size of your object, so you only have to specify coordinates in values from zero to one, and they're scaled to the size of your object automatically for you. userSpaceOnUse essentially takes in absolute units. So you have to know where your object is, and place the gradient at the same place. The radialGradient above would be rewritten:
<radialGradient id="Gradient" cx="60" cy="60" r="50" fx="35" fy="35" gradientUnits="userSpaceOnUse"></radialGradient>
You can also then apply another transformation to the gradient by using the gradientTransform attribute...
Attribute href on Gradients
You can also use the href attribute on gradients too. When it is used, attributes and stops from one gradient can be included on another.
<linearGradient id="Gradient1"> <stop id="stop1" offset="0%" /> <stop id="stop2" offset="50%" /> <stop id="stop3" offset="100%" /> </linearGradient> <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1" xmlns:xlink="http://www.w3.org/1999/xlink" href="#Gradient1" />
We've included the xlink namespace here directly on the node, although usually you would define it at the top of your document.