SVG Gradients
Jakob Jenkov |
SVG gradients are a way of filling shapes with color, in an uneven fashion. That way the fill or stroke of a shape can change from one color to another. This can look really nice for some types of graphics.
Gradient Example
Here is how applying gradients to a shape fill and stroke could look:
The first rectangle has the same stroke color all the way through, but a gradient fill color (light to darker green).
The second rectangle has a gradient applied to both its stroke and fill color.
The third rectangle has a gradient applied to the stroke, but has no fill.
The fourth rectangle has a gradient applied to the fill, but has no stroke.
There are two types of gradients:
- Linear Gradients
- Radial Gradients
Both of these are covered in the following sections.
Linear Gradients
Linear gradients changes evenly from one color to another in a linear fashion. You already saw some simple examples of linear gradients in the beginning of this text.
The color can change either vertically, horizontally, or along a vector you define. You can also just fill part of a shape with a gradient instead of the whole shape. Here are a few visual examples before we continue onto the explanation:
The first rectangle uses a vertical gradient. The second rectangle uses a horizontal gradient. The third rectangle uses a diagonal gradient (gets darker towards lower right corner). The fourth rectangle only fills the right half of the rectangle with gradient. All this is possible using SVG's linear gradients.
Linear gradients are defined using the <linearGradient>
element. Here is an example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <linearGradient id="myLinearGradient1" x1="0%" y1="0%" x2="0%" y2="100%" spreadMethod="pad"> <stop offset="0%" stop-color="#00cc00" stop-opacity="1"/> <stop offset="100%" stop-color="#006600" stop-opacity="1"/> </linearGradient> </defs> <rect x="10" y="10" width="75" height="100" rx="10" ry="10" style="fill:url(#myLinearGradient1); stroke: #005000; stroke-width: 3;" /> </svg>
As you can see the <linearGradient>
-element is nested inside
a <defs>
-element. Gradient definitions must always be nested
inside a <defs>
-element, so you can reference them later in
the SVG image. In this example the linear gradient is referenced by the
<rect>
-element inside its style
attribute,
in the fill
CSS property (fill:url(#myLinearGradient1)
)
The <linearGradient>
-element has two nested <stop>
-elements.
The <linearGradient>
-element controls the direction of the gradient and what happens
before and after the gradient is applied (the spreadMethod
attribute).
The <stop>
-elements control the colors used in the gradient, how far into the
shape the colors start and stop, plus the opacity of the gradient.
Here is a list of the attributes of the <linearGradient>
-element:
Attribute | Description |
id | A unique ID used to reference this gradient definition from shapes. |
x1, y1 | The x1 and y1 (starting point) of the vector defining the direction of the gradient. Specified as percentages (%) of x1,y1 and x2,y2 of the shape the gradient is applied to. (Note: You should be able to use absolute numbers, but this doesn't seem to work in the browsers). |
x2, y2 | The x2 and y2 (end point) of the vector defining the direction of the gradient. |
spreadMethod | This value defines how the gradient is spread out through the shape. There are 3
possible values: pad, repeat, and reflect. 'pad' means that the first/last color
of the gradient is padded (spread out) before and after the gradient. ''repeat'
means that the gradient is repeated throughout the shape. 'reflect' means that
gradient is mirrored in the shape. The spread method is only relevant if the
gradient does not fill out the shape completely (see offset
attributes of the <stop> elements).
|
gradientTransform | You can transform (e.g. rotate) the gradient before it is applied. See SVG Transformation for more details. |
gradientUnits | Sets whether you want to use the viewbox ('userSpaceOnUse') or the the shape the gradient is applied to, for the calculation of x1, y1 and x2,y2. |
xlink:href | An id of another gradient from which this gradient should 'inherit' its attributes. In other words, for any attribute the attribute value of the referenced gradient will be the default value of this gradient, if no attribute value is set in this gradient. |
Here is a list of the <stop>
element attributes:
Attribute | Description |
offset | How far into the shape this color starts (if the first color of the gradient) or stops (if the last color of the gradient). Specified as percentages of the shape (really the gradient vector) the gradient is applied to. For instance, 10% means that the color should start / stop 10% into the shape. |
stop-color | The color of this stop-point. The color the gradient changes from / to. |
The opacity of the color of this stop-point. If opacity changes from one stop-point with 1 to another stop-point with opacity 0, then the color will gradually become more and more transparent. |
Reading all of these attribute descriptions can be very confusing. Therefore I have created an image that illustrates the meaning of these attributes:
And here is the linear gradient definition matching the image:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <linearGradient id="myLinearGradient1" x1="0%" y1="0%" x2="100%" y2="0%" spreadMethod="pad"> <stop offset="10%" stop-color="#00cc00" stop-opacity="1"/> <stop offset="30%" stop-color="#006600" stop-opacity="1"/> <stop offset="70%" stop-color="#cc0000" stop-opacity="1"/> <stop offset="90%" stop-color="#000099" stop-opacity="1"/> </linearGradient> </defs> <rect x="10" y="10" width="500" height="50" rx="10" ry="10" style="fill:url(#myLinearGradient1); stroke: #005000; stroke-width: 3;" /> </svg>
The first stop color is #00cc00 which is to begin 10% into the rectangle.
Because the spreadMethod
is set to "pad", the first color
is also filled into the rectangle before the first stop color (0-10%).
From the first stop color at 10% the color changes towards the second stop color, #006600, which is reached 30% into the rectangle.
From the second stop color at 30% the color changes to the third stop color, #cc0000 (red), which is reached 70% into the rectangle.
From the third stop color at 70% the color changes towards the fourth and final stop color,
#000099 (blue), which is reached at 90%. From 90% and the rest of the rectangle the last
stop color (#000099) is filled into the rectangle, because the spreadMethod
attribute of the <linearGradient>
element is set to "pad".
Radial Gradients
Radial gradients are gradients in which the colors change circularly rather than linearly. Here is an example image:
As you can see the colors now change in a circular fashion. The three last (green) rectangles only vary in the center of the radiation of the lightest green color. The first green rectangle has the colors spread out from the center of the rectangle. The second rectangle uses the top mid of the rectangle. The third rectangle uses the top left corner as center.
Radial gradients are defined using the <radialGradient>
element. Here is an example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <radialGradient id="myRadialGradient4" fx="5%" fy="5%" r="65%" spreadMethod="pad"> <stop offset="0%" stop-color="#00ee00" stop-opacity="1"/> <stop offset="100%" stop-color="#006600" stop-opacity="1" /> </radialGradient> </defs> <rect x="340" y="10" width="100" height="100" rx="10" ry="10" style="fill:url(#myRadialGradient4); stroke: #005000; stroke-width: 3;" /> </svg>
This SVG code actually defines the 4th rectangle shown in the example above.
Notice how the colors are defined using <stop>
elements
just like for linear gradients (see linear gradients for an explanation).
Here is a list of the attributes of the <radialGradient>
element:
Attribute | Description |
id | A unique ID used to reference this gradient definition from shapes. |
cx, cy | The x and y of the center of the radial gradient. Specified as percentages of width and height of shape to fill. Both defaults to 50% if omitted. |
fx, fy | The x and y of the focal point of the radial gradient. Specified as
percentages of width and height of shape to fill. Both defaults to 50% if omitted. NOTE: Firefox 3.0.5 seems to have problems with values below 5%. |
r | The radius of the gradient. |
spreadMethod | This value defines how the gradient is spread out through the shape. There are 3
possible values: pad, repeat, and reflect. 'pad' means that the first/last color
of the gradient is padded (spread out) before and after the gradient. ''repeat'
means that the gradient is repeated throughout the shape. 'reflect' means that
gradient is mirrored in the shape. The spread method is only relevant if the
gradient does not fill out the shape completely (see offset
attributes of the <stop> elements).
|
gradientTransform | You can transform (e.g. rotate) the gradient before it is applied. See SVG Transformation for more details about transformations in general. |
gradientUnits | Sets whether you want to use the viewbox ('userSpaceOnUse') or the the shape the gradient is applied to, for the calculation of x1, y1 and x2,y2. You can often omit this attribute. |
xlink:href | An id of another gradient from which this gradient should 'inherit' its attributes. In other words, for any attribute the attribute value of the referenced gradient will be the default value of this gradient, if no attribute value is set in this gradient. |
The center of a radial gradient is the center of the circular color spread. If you picture your radial gradient as being a circle, cx and cy marks the center of this circle.
The focal point of a radial gradient is the "angle" of the color radiation. If you think of the radial gradient as a lamp, the focal point decides what angle the light from the lamp hits the shape with. 50%, 50% means directly from above. 5%, 5% means from the top left corner and down. The gradient then looks a bit like a light source hitting your shape.
You will most likely have to play around with the center and focal point of your gradients before you get them right. I know I did that, just to create these simple samples.
Transforming Gradients
You can transform a gradient using the standard SVG Transformation functions.
You do so using the gradientTransform
attribute in either the <linearGradient>
and
<radialGradient>
. Here is an example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <linearGradient id="myLinearGradient1" x1="0%" y1="0%" x2="0%" y2="100%" spreadMethod="pad" gradientTransform="rotate(45)" > <stop offset="0%" stop-color="#00cc00" stop-opacity="1"/> <stop offset="100%" stop-color="#006600" stop-opacity="1"/> </linearGradient> </defs> <rect x="10" y="10" width="75" height="100" rx="10" ry="10" style="fill:url(#myLinearGradient1); stroke: #005000; stroke-width: 3;" /> </svg>
This example defines a linear gradient with a gradientTransform()
attribute,
which rotates the gradient 45 degrees. Normally the gradient would have graded the color
from top to bottom, but with the rotation it now goes from the upper right corner to the
lower left corner.
Here is the resulting image:
Tweet | |
Jakob Jenkov |