If you know about CSS, you probably already know a lot about gradients, so let me just give you a quick overview here.
Gradients fill a shape with an uneven colour – this could be just multiple colours or a pattern, but people usually stick to a gradually changing colour. For these, we need to set a gradient direction and size in its main element, and we need to set so-called colour stops within it. These colour stops are just places within the gradient where the colour changes – the previous colour stops there, and a new one begins.
Gradients are defined within the
<defs> element, and applied to an element with
A single colour stop is set with the syntax
<stop stop-color=”color” stop-opacity=”opacity” offset=”position” />
The first two attributes determine the colour, while the third is a percentage that represents the spot at which to change into this colour. It is a percentage, where
0% is the start point of the gradient, and
100% the end point.
Linear vs Radial
A gradient can start at one edge of the shape, and extend in a direct line to the opposite edge. This is a linear gradient.
But, we can also start at some point within the shape, and extend in all directions to make a circle or ellipse. This is a radial gradient.
For linear gradients, the syntax is:
<linearGradient x1=”val” y1=”val” x2=”val” y2=”val” spreadMethod=”method”>
… colour stops …
Here, the point
(x1, y1) is the starting point, and
(x2, y2) the end point. If one of these points is not at the edge of the gradient, this means there’s still some space left to fill within the shape. The
spreadMethod attribute takes care of that, which has three possible values:
pad: the first and last colour step are extended towards the edges of the shape
repeat: the whole gradient is repeated as often as it takes to fill the shape
reflect: the gradient is repeated, but mirrored/reflected every time it does so
<svg> <defs> <linearGradient id="linGrad" x1="0%" y1="0%" x2="100%" y2="100%" spreadMethod="pad"> <stop stop-color="red" offset="0%" /> <stop stop-color="orange" offset="100%" /> </linearGradient> </defs> <rect x="10" y="10" width="100" height="100" fill="url(#linGrad)"/> </svg>
For radial gradients, the syntax is:
<radialGradient cx=”val” cy=”val” fx=”val” fy=”val” r=”val” spreadMethod=”method”>
… colour stops …
The coordinate (
cy) is the centre point of the gradient, or where it is placed. But, (
fy) is the focal point, which means the point at which the first colour stop starts. The
r attribute sets the radius or size of the gradient.
<svg> <defs> <radialGradient id="radGrad" cx="50%" cy="50%" fx="20%" fy="20%" spreadMethod="pad"> <stop stop-color="red" offset="0%" /> <stop stop-color="orange" offset="100%" /> </radialGradient> </defs> <rect x="10" y="10" width="100" height="100" fill="url(#radGrad)"/> </svg>
Another way of customizing the fill of an object is by using patterns. A pattern is simply a group of shapes, which, when used on a shape, tile across the full width and height of the shape. For example, if wanted a dotted fill for an object, we’d create a pattern consisting of a single (small) circle, which would then automatically fill the whole object with these dots.
A pattern must be created within a
<defs> element, with the following syntax:
<pattern id=”name” x=”xPos” y=”yPos” width=”width” height=”height”>
… your shapes …
y attributes set where the pattern starts, relative to the shape’s top left corner. The
height attributes set the size of a single tile within the pattern.
To use it on an element, set
. Notice the similarity with other
url(#name) syntaxes here, which means you can also put patterns and gradients into another pattern!
One important thing to note here is that if you make a shape larger, the size of each tile stays the same, and more tiles are added to fill the available space.
patternContentUnits attribute changes this. It has two possible values:
userSpaceOnUse: Default, does what I just described.
objectBoundingBox: Stretches the tiles instead, to make the pattern fit the object’s dimensions exactly.
patternUnits attribute is for setting the coordinate system of the pattern. It has two possible values:
objectBoundingBox: Default, uses the bounding box of the object.
userSpaceOnUse: uses the coordinate system that was in place at the time the pattern was created.
<svg> <defs> <pattern id="myPattern" width="0.25" height="0.25" patternContentUnits="objectBoundingBox"> <circle cx="0.125" cy="0.125" r="0.1" fill="red" /> </pattern> </defs> <rect x="10" y="10" width="120" height="120" fill="url(#myPattern)" stroke="black" /> </svg>