mozilla

Revision 22545 of Fills and Strokes

  • Revision slug: SVG/Tutorial/Fills_and_Strokes
  • Revision title: Fills and Strokes
  • Revision id: 22545
  • Created:
  • Creator: trevorh
  • Is current revision? No
  • Comment Minor cleanup; 12 words added, 20 words removed

Revision Content

{{ PreviousNext("SVG/Tutorial/Paths", "SVG/Tutorial") }}

So now with your knowledge of how to draw all sorts of shapes, your next goal is probably coloring them in. There are several ways to do this, including specifying attributes on the object, using inline CSS, using an embedded CSS section, or using an external CSS file. Most SVG you'll find around the web uses inline CSS, but there are advantages and disadvantages for all the types.

Fill and Stroke Attributes

Painting

Its been a bit difficult to avoid putting some of this in your face up until now, but in case you haven't noticed, most basic coloring can be done by setting two attributes on the node: fill and stroke. Fill sets the color inside the object and stroke sets the color of the line drawn around the object. You can use the same css color naming schemes that you use in HTML, whether that's color names (that is red), rgb values (that is rgb(255,0,0)), hex values, rgba values, etc.

 <rect x="10" y="10" width="100" height="100" stroke="blue" fill="purple"
       fill-opacity="0.5" stroke-opacity="0.8"/>

In addition, you can specify the opacity of either the fill or stroke separately in SVG. These are controlled by the fill-opacity and stroke-opacity attributes. Note, in FF3 rgba values are also allowed, and will give the same effect, but for compatibility with other viewers, its often best to specify the fill/stroke opacity separately. If you specify both an rgba value and a fill/stroke opacity value, both will be applied.

Stroke

In addition to just its color properties, there are a few other attributes available to control the way a stroke is drawn on a line.

<?xml version="1.0" standalone="no"?>
<svg width="160" height="140" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <line x1="40" x2="120" y1="20" y2="20" stroke="black" stroke-width="20" stroke-linecap="butt"/>
  <line x1="40" x2="120" y1="60" y2="60" stroke="black" stroke-width="20" stroke-linecap="square"/>
  <line x1="40" x2="120" y1="100" y2="100" stroke="black" stroke-width="20" stroke-linecap="round"/>
</svg>

Before I discuss these, I just want to note that strokes are drawn so that they are centered around the path, that is, in the example above the path is shown in pink, and the stroke in black. The stroke-width property defines the width of this stroke. As you can see the stroke is distributed evenly on both sides of the path.

The second of these is the stroke-linecap property, demoed above. This controls the shape shown at the end of lines. There are three possible values for it. butt closes the line off with a straight edge that's normal (at 90 degrees to) the direction of the stroke and crosses its end. square has essentially the same appearance, but stretches the stroke slightly beyond the actual path. The distance that the stroke goes beyond the path is controlled by the stroke-width property. round produces a rounded effect on the end of the stroke, The radius of this curve is, again, controlled by the stroke width.

There is also a property, stroke-linejoin to control how the line is drawn at the joint between two line segments.

<?xml version="1.0" standalone="no"?>
<svg width="160" height="280" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <polyline points="40 60 80 20 120 60" stroke="black" stroke-width="20"
      stroke-linecap="butt" fill="transparent" stroke-linejoin="miter"/>
  
  <polyline points="40 140 80 100 120 140" stroke="black" stroke-width="20"
      stroke-linecap="round" fill="transparent" stroke-linejoin="round"/>
  
  <polyline points="40 220 80 180 120 220" stroke="black" stroke-width="20"
      stroke-linecap="square" fill="transparent" stroke-linejoin="bevel"/>
</svg>

Each of these polylines have two segments. The joint where the two meet is controlled by the stroke-linejoin attribute. There are three possible values for this attribute. miter will extend the line slightly beyond its normal width to create a square corner where only one angle is used. round, again draws a rounded line segment. bevel will create a new angle to aid in the transition between the two segments.

Finally, you can also use dashed line types on a stroke, by specifying the stroke-dasharray attribute.

<?xml version="1.0" standalone="no"?>
<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <path d="M 10 75 Q 50 10 100 75 T 190 75" stroke="black"
    stroke-linecap="round" stroke-dasharray="5,10,5" fill="none"/>
  <path d="M 10 75 L 190 75" stroke="red"
    stroke-linecap="round" stroke-width="1" stroke-dasharray="5,5" fill="none"/>
</svg>

The stroke-dasharray attribute takes as an argument a series of comma separated numbers. Note, unlike paths these numbers must be comma separated. You can insert whitespace too if you want, but the numbers must have commas in between them. Each of the numbers specifies a distance for first the filled area, and then for the unfilled area. So in the above example, the second path fills 5 pixel units, then leaves 5 blank, then fills 5 again. You can specify more numbers if you would like a more complicated dash pattern. The first example specifies three numbers, in which case the renderer loops the numbers twice to create an even pattern. So the first path renders 5 filled, 10 empty, 5 filled, and then loops back to create 5 empty, 10 filled, 5 empty. The pattern then loops again.

There are a few additional stroke and fill properties available, including fill-rule which specifies how to color in shapes that overlap themselves, stroke-miterlimit which deals with a stroke should draw miters and when it shouldn't, and stroke-dashoffset which specifies where to start a dasharray on a line.

Using CSS

In addition to setting attributes on objects, you can also use CSS to style fills and strokes on them. The syntax for this is the same as CSS used in normal HTML, except you'll be setting values like fill and stroke instead of background-color or border. I should note that not all attributes can be set via. CSS. Things that deal with painting and filling are usually available, so fill, stroke, stroke-dasharray, etc. can all be set this way, in addition to the gradient and pattern versions of those shown below. Things like width, height, or path commands, d, can't be set through CSS. Its easiest just to test and find out what is available and what isn't. The DOM Inspector in FF3 now also shows a list of SVG CSS attributes, in addition to the XUL and HTML ones.

CSS can be inserted inline with the element via. the style attribute:

 <rect x="10" height="180" y="10" width="180" style="stroke: black; fill: red;"/>

or can be moved to a special style section that you include. Instead of shoving such a section into a <head> like you do in HTML though, its included in an area called <defs>. <defs> stands for definitions, and its here where you can create elements that don't appear in the SVG directly, but are used by other elements.

<?xml version="1.0" standalone="no"?>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <style type="text/css"><![CDATA[
       #MyRect {
         stroke: black;
         fill: red;
       }
    ]]></style>
  </defs>
  <rect x="10" height="180" y="10" width="180" id="MyRect"/>
</svg>

Moving styles to an area like this can make it easier to adjust properties on large groups of elements. You can also use things like the hover pseudo classes to create rollover effects:

 #MyRect:hover {
   stroke: black;
   fill: blue;
 }

The list could go on and on, but you're better off reading a CSS tutorial to learn about it. Some things that work in normal HTML won't work, like the before and after pseudo classes, so a bit of experimentation is needed to sort everything out.

You can also specify an external style sheet for your CSS rules through normal XML-stylesheet syntax:

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet type="text/css" href="style.css"?>

<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <rect height="10" width="10" id="MyRect"/>
</svg>

where style.css looks something like:

#MyRect {
  fill: red;
  stroke: black;
}

Gradients

So, perhaps more exciting than just fills and strokes, you can also create and apply gradients as either fills or strokes.

There are two types of gradients allowed, linear and radial ones. Linear gradients change along a straight line. To insert one, you create a <linearGradient> node inside the definitions section of your SVG file. You MUST give the gradient an id attribute, otherwise it can't be referenced by other elements inside the file, and it basically becomes a waste of space.

<?xml version="1.0" standalone="no"?>

<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
      <linearGradient id="Gradient1">
        <stop class="stop1" offset="0%"/>
        <stop class="stop2" offset="50%"/>
        <stop class="stop3" offset="100%"/>
      </linearGradient>
      <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
        <stop offset="0%" stop-color="red"/>
        <stop offset="50%" stop-color="black" stop-opacity="0"/>
        <stop offset="100%" stop-color="blue"/>
      </linearGradient>
      <style type="text/css"><![CDATA[
        #rect1 { fill: url(#Gradient1); }
        .stop1 { stop-color: red; }
        .stop2 { stop-color: black; stop-opacity: 0; }
        .stop3 { stop-color: blue; }
      ]]></style>
  </defs>
 
  <rect id="rect1" x="10" y="10" rx="15" ry="15" width="100" height="100"/>
  <rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#Gradient2)"/>
  
</svg>

Above is an example of a linear gradient being applied to 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. I've intermixed the two just for the purposes of an example). For instance, this one tells the gradient to start at the color red, change to transparent-black in the middle, and end at the color blue. 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 (again, in FF3 you can also use rgba values to do this).

 <stop offset="100%" stop-color="yellow" stop-opacity="0.5"/>

To use a gradient, we have to reference it from an objects fill or stroke attributes. 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, which I've given the creative id, "Gradient". So to attach it we just set the fill to url(#Gradient), and voila 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 y1. 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.

 <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
Note: You can also use the xlink:href attribute on gradients too. When its used attributes and stops from one gradient can be included on another. In the above example, you wouldn't have to recreate all the stops in Gradient2.
 <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" xlink:href="#Gradient1"/>
I've included the xlink namespace here directly on the node, although usually you would define it at the top of your document. More on that when we talk about images.

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 definitions section of your document.

<?xml version="1.0" standalone="no"?>

<svg width="120" height="240" version="1.1"
  xmlns="http://www.w3.org/2000/svg">
  <defs>
      <radialGradient id="Gradient1">
        <stop offset="0%" stop-color="red"/>
        <stop offset="100%" stop-color="blue"/>
      </radialGradient>
      <radialGradient id="Gradient2" 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(#Gradient1)"/> 
  <rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#Gradient2)"/> 
  
</svg>

The stops used here are the same as before, but now the object will be red in the center, and in all directions gradually change to blue at the edge. Like linear gradients, the <radialGradient> node can take several attributes to describe its position and orientation. However, unlike linear gradients, its 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 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.

<?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, its impossible for the gradient to be rendered correctly, so the spot will be assumed to be on the edge of the circle. If the focal point isn't given at all, its assumed to be at the same place as the center point.

Both gradients also take a few other attributes to describe transformations and whatnot on them. 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 just used to fill the rest of the object. "reflect" causes the gradient to continue on, but this take backwards, starting with the color offset at 100% and moving back to the offset at 0%, and then back up again. "reflect" also lets the gradient keep moving, but instead of going backwards, it just jumps back to the beginning and runs again.

<?xml version="1.0" standalone="no"?>

<svg width="220" height="220" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
      <radialGradient id="Gradient"
            cx="0.5" cy="0.5" r="0.25" fx=".25" fy=".25"
            spreadMethod="repeat">
        <stop offset="0%" stop-color="red"/>
        <stop offset="100%" stop-color="blue"/>
      </radialGradient>
  </defs>
  <rect x="50" y="50" rx="15" ry="15" width="100" height="100"
       fill="url(#Gradient)"/>
</svg>

As a bit of another aside here, both gradients also have an attribute named gradientUnits that 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 I've 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">

You can also then apply another transformation to the gradient by using the gradientTransform attribute, but since we haven't introduced transforms yet, I'll leave that for later.

There are some other caveats for dealing with gradientUnits="objectBoundingBox" when the object bounding box isn't square, but they're fairly complex and will have to wait for someone more in-the-know to explain them.

Patterns

Patterns, in my opinion, are one of the more confusing fill types to use in SVG. They're also very powerful, so they're worth talking about and getting at least a fundamental grasp on. Like gradients, the <pattern> element should be put in the <defs> section of your SVG file.

<?xml version="1.0" standalone="no"?>
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <defs>
    <linearGradient id="Gradient1">
      <stop offset="5%" stop-color="white"/>
      <stop offset="95%" stop-color="blue"/>
    </linearGradient>
    <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
      <stop offset="5%" stop-color="red"/>
      <stop offset="95%" stop-color="orange"/>
    </linearGradient>

    <pattern id="Pattern" x=".05" y=".05" width=".25" height=".25">
      <rect x="0" y="0" width="50" height="50" fill="skyblue"/>
      <rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)"/>
      <circle cx="25" cy="25" r="20" fill="url(#Gradient1)" fill-opacity="0.5"/>
    </pattern> 

  </defs>
  
  <rect fill="url(#Pattern)" stroke="black" x="0" y="0" width="200" height="200"/>
</svg>

Inside the pattern element you can include any of the other basic shapes you've included before, and each of them can be styled using any of the styles you've learned before, including gradients and opacity. Here we've just drawn two rectangle elements inside our pattern (which overlap, and one of which is twice the size of the other and is used to fill in the entire pattern), and one circle.

The confusing thing about patterns is defining a unit system and their size. In the example above, we've defined a width and height attribute on the pattern element, to describe how far the pattern should go before it begins repeating itself again. There are also x and y attributes available if you want to offset the start point of this rectangle somewhere within your drawing. The reason they've been used here is described below.

As with the gradientUnits attribute used above, patterns also have an attribute, patternUnits which specifies the units that these attributes will take. It defaults to "objectBoundingBox" as it did above, so a value of 1 is scaled to the width/height of the object you're applying the pattern to. Since, in this case, we wanted the pattern to repeat 4 times horizontally and vertically, the height and width are set to 0.25. That means the patterns width/height is only 0.25 of the total box size.

Unlike gradients, patterns then have a second attribute, patternContentUnits, which describes the units system used inside the pattern element, on the basic shapes themselves. This attribute defaults to "userSpaceOnUse", the opposite of the patternUnits attribute. What this means is that unless you specify one or both of these attributes (patternContentUnits and patternUnits), the shapes you draw inside your pattern are being drawn in a different coordinate system than the pattern element is using, which can make things a bit confusing when you're writing this by hand. To make this work in the above example, we had to consider the size of our box (200 pixels) and the fact that we wanted the pattern to repeat itself 4 times horizontally and vertically. That means that each pattern unit was a 50x50 square. The two rects and the circle inside the pattern were then sized to fit in a 50x50 box. Anything that we had drawn outside that box wouldn't have been shown. The pattern also had to be offset by 10 pixels so that it would start in the upper left corner of our box, so the x and y attributes of the pattern had to be adjusted to 10/200 = 0.05.

The caveot here is that if the object changes size, the pattern itself will scale to fit it, but the objects inside will not. So while we would still have 4 repeating units inside the pattern, the objects composing that pattern would remain the same size, and you end up with large areas of nothing in between them. By changing the patternContentUnits attribute, we can put all the elements into the same unit system:

 <pattern id="Pattern" width=".25" height=".25" patternContentUnits="objectBoundingBox">
   <rect x="0" y="0" width=".25" height=".25" fill="skyblue"/>
   <rect x="0" y="0" width=".125" height=".125" fill="url(#Gradient2)"/>
   <circle cx=".125" cy=".125" r=".1" fill="url(#Gradient1)" fill-opacity="0.5"/>
 </pattern>

Now, because the pattern content is in the same unit system as the pattern, we don't have to offset the box so that the pattern starts in the correct place, and if the object size was changed to a larger one, the pattern would automatically scale so that it had the same number of objects and repeats inside it. This contrasts with the "userSpaceOnUse" system, where if the object changes size the pattern would stay the same, and just repeat itself more times to fill the box.

As a slight aside, in Gecko circles seem to have trouble drawing if their radius is set to something less than 0.075 (even though they should be scaled up to have a much larger radius than that. This may be a bug in just the pattern element, or not a bug at all, I'm not sure). To work around that its probably best to avoid drawing in "objectBoundingBox" units unless you have to.

Neither of these uses is what one would normally think of when you think of a pattern. Patterns usually have a set size and repeat themselves independently of what an objects shape is. To create something like this, both the pattern and its contents must be drawn in the current userSpace, so that they don't change shape if the object does:

 <pattern id="Pattern" x="10" y="10" width="50" height="50" patternUnits="userSpaceOnUse">
   <rect x="0" y="0" width="50" height="50" fill="skyblue"/>
   <rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)"/>
   <circle cx="25" cy="25" r="20" fill="url(#Gradient1)" fill-opacity="0.5"/>
 </pattern>

Of course, this means that the pattern won't scale if you change your object size later. All three of the above examples are shown below on a rectangle that has been slightly elongated to a height of 300px, but I should note its not an exhaustive picture, and there are other options available depending on your application.

Image:SVG_Pattern_Comparison_of_Units.png

{{ PreviousNext("SVG/Tutorial/Paths", "SVG/Tutorial") }}

Revision Source

<p>{{ PreviousNext("SVG/Tutorial/Paths", "SVG/Tutorial") }}</p>
<p>So now with your knowledge of how to draw all sorts of shapes, your next goal is probably coloring them in. There are several ways to do this, including specifying attributes on the object, using inline CSS, using an embedded CSS section, or using an external CSS file. Most SVG you'll find around the web uses inline CSS, but there are advantages and disadvantages for all the types.</p>
<h2 name="Fill_and_Stroke_Attributes">Fill and Stroke Attributes</h2>
<h3 name="Painting">Painting</h3>
<p>Its been a bit difficult to avoid putting some of this in your face up until now, but in case you haven't noticed, most basic coloring can be done by setting two attributes on the node: <code>fill</code> and <code>stroke</code>. Fill sets the color inside the object and stroke sets the color of the line drawn around the object. You can use the same css color naming schemes that you use in HTML, whether that's color names (that is <em>red</em>), rgb values (that is <em>rgb(255,0,0)</em>), hex values, rgba values, etc.</p>
<pre class="eval"> &lt;rect x="10" y="10" width="100" height="100" stroke="blue" fill="purple"
       fill-opacity="0.5" stroke-opacity="0.8"/&gt;
</pre>
<p>In addition, you can specify the opacity of either the fill or stroke separately in SVG. These are controlled by the <code>fill-opacity</code> and <code>stroke-opacity</code> attributes. Note, in FF3 rgba values are also allowed, and will give the same effect, but for compatibility with other viewers, its often best to specify the fill/stroke opacity separately. If you specify both an rgba value and a fill/stroke opacity value, both will be applied.</p>
<h3 name="Stroke">Stroke</h3>
<p>In addition to just its color properties, there are a few other attributes available to control the way a stroke is drawn on a line.</p>
<p><img align="right" alt="" class=" internal" src="/@api/deki/files/355/=SVG_Stroke_Linecap_Example.png"></p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;
&lt;svg width="160" height="140" xmlns="http://www.w3.org/2000/svg" version="1.1"&gt;
  &lt;line x1="40" x2="120" y1="20" y2="20" stroke="black" stroke-width="20" stroke-linecap="butt"/&gt;
  &lt;line x1="40" x2="120" y1="60" y2="60" stroke="black" stroke-width="20" stroke-linecap="square"/&gt;
  &lt;line x1="40" x2="120" y1="100" y2="100" stroke="black" stroke-width="20" stroke-linecap="round"/&gt;
&lt;/svg&gt;</pre>
<p>Before I discuss these, I just want to note that strokes are drawn so that they are centered around the path, that is, in the example above the path is shown in pink, and the stroke in black. The <code>stroke-width</code> property defines the width of this stroke. As you can see the stroke is distributed evenly on both sides of the path.</p>
<p>The second of these is the <code>stroke-linecap</code> property, demoed above. This controls the shape shown at the end of lines. There are three possible values for it. <code>butt</code> closes the line off with a straight edge that's normal (at 90 degrees to) the direction of the stroke and crosses its end. <code>square</code> has essentially the same appearance, but stretches the stroke slightly beyond the actual path. The distance that the stroke goes beyond the path is controlled by the <code>stroke-width</code> property. <code>round</code> produces a rounded effect on the end of the stroke, The radius of this curve is, again, controlled by the stroke width.</p>
<p>There is also a property, <code>stroke-linejoin</code> to control how the line is drawn at the joint between two line segments.</p>
<p><img align="right" alt="" class=" internal" src="/@api/deki/files/356/=SVG_Stroke_Linejoin_Example.png"></p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;
&lt;svg width="160" height="280" xmlns="http://www.w3.org/2000/svg" version="1.1"&gt;
  &lt;polyline points="40 60 80 20 120 60" stroke="black" stroke-width="20"
      stroke-linecap="butt" fill="transparent" stroke-linejoin="miter"/&gt;
  
  &lt;polyline points="40 140 80 100 120 140" stroke="black" stroke-width="20"
      stroke-linecap="round" fill="transparent" stroke-linejoin="round"/&gt;
  
  &lt;polyline points="40 220 80 180 120 220" stroke="black" stroke-width="20"
      stroke-linecap="square" fill="transparent" stroke-linejoin="bevel"/&gt;
&lt;/svg&gt;</pre>
<p>Each of these polylines have two segments. The joint where the two meet is controlled by the <code>stroke-linejoin</code> attribute. There are three possible values for this attribute. <code>miter</code> will extend the line slightly beyond its normal width to create a square corner where only one angle is used. <code>round</code>, again draws a rounded line segment. <code>bevel</code> will create a new angle to aid in the transition between the two segments.</p>
<p>Finally, you can also use dashed line types on a stroke, by specifying the <code>stroke-dasharray</code> attribute.</p>
<p><img align="right" alt="" class=" internal" src="/@api/deki/files/354/=SVG_Stroke_Dasharray_Example.png"></p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;
&lt;svg width="200" height="150" xmlns="http://www.w3.org/2000/svg" version="1.1"&gt;
  &lt;path d="M 10 75 Q 50 10 100 75 T 190 75" stroke="black"
    stroke-linecap="round" stroke-dasharray="5,10,5" fill="none"/&gt;
  &lt;path d="M 10 75 L 190 75" stroke="red"
    stroke-linecap="round" stroke-width="1" stroke-dasharray="5,5" fill="none"/&gt;
&lt;/svg&gt;</pre>
<p>The <code>stroke-dasharray</code> attribute takes as an argument a series of comma separated numbers. Note, unlike paths these numbers must be comma separated. You can insert whitespace too if you want, but the numbers must have commas in between them. Each of the numbers specifies a distance for first the filled area, and then for the unfilled area. So in the above example, the second path fills 5 pixel units, then leaves 5 blank, then fills 5 again. You can specify more numbers if you would like a more complicated dash pattern. The first example specifies three numbers, in which case the renderer loops the numbers twice to create an even pattern. So the first path renders 5 filled, 10 empty, 5 filled, and then loops back to create 5 empty, 10 filled, 5 empty. The pattern then loops again.</p>
<p>There are a few additional stroke and fill properties available, including <code>fill-rule</code> which specifies how to color in shapes that overlap themselves, <code>stroke-miterlimit</code> which deals with a stroke should draw miters and when it shouldn't, and <code>stroke-dashoffset</code> which specifies where to start a dasharray on a line.</p>
<h2 name="Using_CSS">Using CSS</h2>
<p>In addition to setting attributes on objects, you can also use CSS to style fills and strokes on them. The syntax for this is the same as CSS used in normal HTML, except you'll be setting values like <code>fill</code> and <code>stroke</code> instead of <code>background-color</code> or <code>border</code>. I should note that not all attributes can be set via. CSS. Things that deal with painting and filling are usually available, so <code>fill</code>, <code>stroke</code>, <code>stroke-dasharray</code>, etc. can all be set this way, in addition to the gradient and pattern versions of those shown below. Things like <code>width</code>, <code>height</code>, or path commands, <code>d</code>, can't be set through CSS. Its easiest just to test and find out what is available and what isn't. The DOM Inspector in FF3 now also shows a list of SVG CSS attributes, in addition to the XUL and HTML ones.</p>
<p>CSS can be inserted inline with the element via. the style attribute:</p>
<pre class="eval"> &lt;rect x="10" height="180" y="10" width="180" style="stroke: black; fill: red;"/&gt;
</pre>
<p>or can be moved to a special style section that you include. Instead of shoving such a section into a <code>&lt;head&gt;</code> like you do in HTML though, its included in an area called <code>&lt;defs&gt;</code>. <code>&lt;defs&gt;</code> stands for definitions, and its here where you can create elements that don't appear in the SVG directly, but are used by other elements.</p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;
&lt;svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1"&gt;
  &lt;defs&gt;
    &lt;style type="text/css"&gt;&lt;![CDATA[
       #MyRect {
         stroke: black;
         fill: red;
       }
    ]]&gt;&lt;/style&gt;
  &lt;/defs&gt;
  &lt;rect x="10" height="180" y="10" width="180" id="MyRect"/&gt;
&lt;/svg&gt;</pre>
<p>Moving styles to an area like this can make it easier to adjust properties on large groups of elements. You can also use things like the hover pseudo classes to create rollover effects:</p>
<pre class="eval"> #MyRect:hover {
   stroke: black;
   fill: blue;
 }
</pre>
<p>The list could go on and on, but you're better off reading a CSS tutorial to learn about it. Some things that work in normal HTML won't work, like the <code>before</code> and <code>after</code> pseudo classes, so a bit of experimentation is needed to sort everything out.</p>
<p>You can also specify an external style sheet for your CSS rules through normal XML-stylesheet syntax:</p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;
&lt;?xml-stylesheet type="text/css" href="style.css"?&gt;

&lt;svg width="200" height="150" xmlns="http://www.w3.org/2000/svg" version="1.1"&gt;
  &lt;rect height="10" width="10" id="MyRect"/&gt;
&lt;/svg&gt;</pre>
<p>where style.css looks something like:</p>
<pre>#MyRect {
  fill: red;
  stroke: black;
}</pre>
<h2 name="Gradients">Gradients</h2>
<p>So, perhaps more exciting than just fills and strokes, you can also create and apply gradients as either fills or strokes.</p>
<p>There are two types of gradients allowed, linear and radial ones. Linear gradients change along a straight line. To insert one, you create a <code>&lt;linearGradient&gt;</code> node inside the definitions section of your SVG file. You MUST give the gradient an id attribute, otherwise it can't be referenced by other elements inside the file, and it basically becomes a waste of space.</p>
<p><img align="right" alt="" class=" internal" src="/@api/deki/files/347/=SVG_Linear_Gradient_Example.png"></p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;

&lt;svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg"&gt;
  &lt;defs&gt;
      &lt;linearGradient id="Gradient1"&gt;
        &lt;stop class="stop1" offset="0%"/&gt;
        &lt;stop class="stop2" offset="50%"/&gt;
        &lt;stop class="stop3" offset="100%"/&gt;
      &lt;/linearGradient&gt;
      &lt;linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1"&gt;
        &lt;stop offset="0%" stop-color="red"/&gt;
        &lt;stop offset="50%" stop-color="black" stop-opacity="0"/&gt;
        &lt;stop offset="100%" stop-color="blue"/&gt;
      &lt;/linearGradient&gt;
      &lt;style type="text/css"&gt;&lt;![CDATA[
        #rect1 { fill: url(#Gradient1); }
        .stop1 { stop-color: red; }
        .stop2 { stop-color: black; stop-opacity: 0; }
        .stop3 { stop-color: blue; }
      ]]&gt;&lt;/style&gt;
  &lt;/defs&gt;
 
  &lt;rect id="rect1" x="10" y="10" rx="15" ry="15" width="100" height="100"/&gt;
  &lt;rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#Gradient2)"/&gt;
  
&lt;/svg&gt;</pre>
<p>Above is an example of a linear gradient being applied to a <code>&lt;rect&gt;</code> element. Inside the linear gradient are several <code>&lt;stop&gt;</code> nodes. These nodes tell the gradient what color it should be at certain positions by specifying an <code>offset</code> attribute for the position, and a <code>stop-color</code> attribute (this can be assigned directly or through CSS. I've intermixed the two just for the purposes of an example). For instance, this one tells the gradient to start at the color red, change to transparent-black in the middle, and end at the color blue. 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 <code>stop-opacity</code> attribute to set the opacity at that position (again, in FF3 you can also use rgba values to do this).</p>
<pre class="eval"> &lt;stop offset="100%" stop-color="yellow" stop-opacity="0.5"/&gt;
</pre>
<p>To use a gradient, we have to reference it from an objects fill or stroke attributes. This is done the same way you reference elements in CSS, using a <code>url</code>. In this case, the url is just a reference to our gradient, which I've given the creative id, "Gradient". So to attach it we just set the fill to <code>url(#Gradient)</code>, and voila our object is now multicolored. You can do the same with stroke.</p>
<p>The <code>&lt;linearGradient&gt;</code> 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 <code>x1</code>, <code>x2</code>, <code>y1</code>, and <code>y1</code>. 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.</p>
<pre class="eval"> &lt;linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1"&gt;
</pre>
<div class="note"><strong>Note:</strong> You can also use the <code>xlink:href</code> attribute on gradients too. When its used attributes and stops from one gradient can be included on another. In the above example, you wouldn't have to recreate all the stops in Gradient2.
<pre class="eval"> &lt;linearGradient id="Gradient1"&gt;
   &lt;stop id="stop1" offset="0%"/&gt;
   &lt;stop id="stop2" offset="50%"/&gt;
   &lt;stop id="stop3" offset="100%"/&gt;
 &lt;/linearGradient&gt;
 &lt;linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1"
    xmlns:xlink="<a class=" external" href="http://www.w3.org/1999/xlink" rel="freelink">http://www.w3.org/1999/xlink</a>" xlink:href="#Gradient1"/&gt;
</pre>
I've included the xlink namespace here directly on the node, although usually you would define it at the top of your document. More on that when we talk about images.</div>
<p>Radial gradients are similar to linear ones but draw a gradient that radiates out from a point. To create one you add a <code>&lt;radialGradient&gt;</code> element to the definitions section of your document.</p>
<p><img align="right" alt="" class=" internal" src="/@api/deki/files/351/=SVG_Radial_Gradient_Example.png"></p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;

&lt;svg width="120" height="240" version="1.1"
  xmlns="http://www.w3.org/2000/svg"&gt;
  &lt;defs&gt;
      &lt;radialGradient id="Gradient1"&gt;
        &lt;stop offset="0%" stop-color="red"/&gt;
        &lt;stop offset="100%" stop-color="blue"/&gt;
      &lt;/radialGradient&gt;
      &lt;radialGradient id="Gradient2" cx="0.25" cy="0.25" r="0.25"&gt;
        &lt;stop offset="0%" stop-color="red"/&gt;
        &lt;stop offset="100%" stop-color="blue"/&gt;
      &lt;/radialGradient&gt;
  &lt;/defs&gt;
 
  &lt;rect x="10" y="10" rx="15" ry="15" width="100" height="100" fill="url(#Gradient1)"/&gt; 
  &lt;rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#Gradient2)"/&gt; 
  
&lt;/svg&gt;</pre>
<p>The stops used here are the same as before, but now the object will be red in the center, and in all directions gradually change to blue at the edge. Like linear gradients, the <code>&lt;radialGradient&gt;</code> node can take several attributes to describe its position and orientation. However, unlike linear gradients, its 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 <code>cx</code> and <code>cy</code> attributes, and a radius, <code>r</code>. Setting these three attributes will allow you to move the gradient around and change its size, as shown in the second rect above.</p>
<p>The second point is called the focal point and is defined by the <code>fx</code> and <code>fy</code> 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.</p>
<p><img align="right" alt="" class=" internal" src="/@api/deki/files/352/=SVG_Radial_Grandient_Focus_Example.png"></p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;

&lt;svg width="120" height="120" version="1.1"
  xmlns="http://www.w3.org/2000/svg"&gt;
  &lt;defs&gt;
      &lt;radialGradient id="Gradient"
            cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25"&gt;
        &lt;stop offset="0%" stop-color="red"/&gt;
        &lt;stop offset="100%" stop-color="blue"/&gt;
      &lt;/radialGradient&gt;
  &lt;/defs&gt;
 
  &lt;rect x="10" y="10" rx="15" ry="15" width="100" height="100"
        fill="url(#Gradient)" stroke="black" stroke-width="2"/&gt;

  &lt;circle cx="60" cy="60" r="50" fill="transparent" stroke="white" stroke-width="2"/&gt;
  &lt;circle cx="35" cy="35" r="2" fill="white" stroke="white"/&gt;
  &lt;circle cx="60" cy="60" r="2" fill="white" stroke="white"/&gt;
  &lt;text x="38" y="40" fill="white" font-family="sans-serif" font-size="10pt"&gt;(fx,fy)&lt;/text&gt;
  &lt;text x="63" y="63" fill="white" font-family="sans-serif" font-size="10pt"&gt;(cx,cy)&lt;/text&gt;
  
&lt;/svg&gt;</pre>
<p>If the focal point is moved outside the circle described earlier, its impossible for the gradient to be rendered correctly, so the spot will be assumed to be on the edge of the circle. If the focal point isn't given at all, its assumed to be at the same place as the center point.</p>
<p>Both gradients also take a few other attributes to describe transformations and whatnot on them. The only other one I want to mention here is the <code>spreadMethod</code> 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 just used to fill the rest of the object. "reflect" causes the gradient to continue on, but this take backwards, starting with the color offset at 100% and moving back to the offset at 0%, and then back up again. "reflect" also lets the gradient keep moving, but instead of going backwards, it just jumps back to the beginning and runs again.</p>
<p><img align="right" alt="" class=" internal" src="/@api/deki/files/353/=SVG_SpreadMethod_Example.png"></p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;

&lt;svg width="220" height="220" version="1.1" xmlns="http://www.w3.org/2000/svg"&gt;
  &lt;defs&gt;
      &lt;radialGradient id="Gradient"
            cx="0.5" cy="0.5" r="0.25" fx=".25" fy=".25"
            spreadMethod="repeat"&gt;
        &lt;stop offset="0%" stop-color="red"/&gt;
        &lt;stop offset="100%" stop-color="blue"/&gt;
      &lt;/radialGradient&gt;
  &lt;/defs&gt;
  &lt;rect x="50" y="50" rx="15" ry="15" width="100" height="100"
       fill="url(#Gradient)"/&gt;
&lt;/svg&gt;</pre>
<p>As a bit of another aside here, both gradients also have an attribute named <code>gradientUnits</code> that 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: <code>userSpaceOnUse</code> or <code>objectBoundingBox</code>. <code>objectBoundingBox</code> is the default so that's what I've 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. <code>userSpaceOnUse</code> 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:</p>
<pre class="eval"> &lt;radialGradient id="Gradient" cx="60" cy="60" r="50" fx="35" fy="35" gradientUnits="userSpaceOnUse"&gt;
</pre>
<p>You can also then apply another transformation to the gradient by using the <code>gradientTransform</code> attribute, but since we haven't introduced transforms yet, I'll leave that for later.</p>
<p>There are some other caveats for dealing with <code>gradientUnits="objectBoundingBox"</code> when the object bounding box isn't square, but they're fairly complex and will have to wait for someone more in-the-know to explain them.</p>
<h2 name="Patterns">Patterns</h2>
<p>Patterns, in my opinion, are one of the more confusing fill types to use in SVG. They're also very powerful, so they're worth talking about and getting at least a fundamental grasp on. Like gradients, the <code>&lt;pattern&gt;</code> element should be put in the <code>&lt;defs&gt;</code> section of your SVG file.</p>
<p><img align="right" alt="" class=" internal" src="/@api/deki/files/350/=SVG_Pattern_Example.png"></p>
<pre>&lt;?xml version="1.0" standalone="no"?&gt;
&lt;svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1"&gt;
  &lt;defs&gt;
    &lt;linearGradient id="Gradient1"&gt;
      &lt;stop offset="5%" stop-color="white"/&gt;
      &lt;stop offset="95%" stop-color="blue"/&gt;
    &lt;/linearGradient&gt;
    &lt;linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1"&gt;
      &lt;stop offset="5%" stop-color="red"/&gt;
      &lt;stop offset="95%" stop-color="orange"/&gt;
    &lt;/linearGradient&gt;

    &lt;pattern id="Pattern" x=".05" y=".05" width=".25" height=".25"&gt;
      &lt;rect x="0" y="0" width="50" height="50" fill="skyblue"/&gt;
      &lt;rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)"/&gt;
      &lt;circle cx="25" cy="25" r="20" fill="url(#Gradient1)" fill-opacity="0.5"/&gt;
    &lt;/pattern&gt; 

  &lt;/defs&gt;
  
  &lt;rect fill="url(#Pattern)" stroke="black" x="0" y="0" width="200" height="200"/&gt;
&lt;/svg&gt;</pre>
<p>Inside the pattern element you can include any of the other basic shapes you've included before, and each of them can be styled using any of the styles you've learned before, including gradients and opacity. Here we've just drawn two rectangle elements inside our pattern (which overlap, and one of which is twice the size of the other and is used to fill in the entire pattern), and one circle.</p>
<p>The confusing thing about patterns is defining a unit system and their size. In the example above, we've defined a <code>width</code> and <code>height</code> attribute on the pattern element, to describe how far the pattern should go before it begins repeating itself again. There are also <code>x</code> and <code>y</code> attributes available if you want to offset the start point of this rectangle somewhere within your drawing. The reason they've been used here is described below.</p>
<p>As with the <code>gradientUnits</code> attribute used above, patterns also have an attribute, <code>patternUnits</code> which specifies the units that these attributes will take. It defaults to "objectBoundingBox" as it did above, so a value of 1 is scaled to the width/height of the object you're applying the pattern to. Since, in this case, we wanted the pattern to repeat 4 times horizontally and vertically, the height and width are set to 0.25. That means the patterns width/height is only 0.25 of the total box size.</p>
<p>Unlike gradients, patterns then have a second attribute, <code>patternContentUnits</code>, which describes the units system used inside the pattern element, on the basic shapes themselves. This attribute defaults to "userSpaceOnUse", the opposite of the <code>patternUnits</code> attribute. What this means is that unless you specify one or both of these attributes (<code>patternContentUnits</code> and <code>patternUnits</code>), the shapes you draw inside your pattern are being drawn in a different coordinate system than the pattern element is using, which can make things a bit confusing when you're writing this by hand. To make this work in the above example, we had to consider the size of our box (200 pixels) and the fact that we wanted the pattern to repeat itself 4 times horizontally and vertically. That means that each pattern unit was a 50x50 square. The two rects and the circle inside the pattern were then sized to fit in a 50x50 box. Anything that we had drawn outside that box wouldn't have been shown. The pattern also had to be offset by 10 pixels so that it would start in the upper left corner of our box, so the x and y attributes of the pattern had to be adjusted to 10/200 = 0.05.</p>
<p>The caveot here is that if the object changes size, the pattern itself will scale to fit it, but the objects inside will not. So while we would still have 4 repeating units inside the pattern, the objects composing that pattern would remain the same size, and you end up with large areas of nothing in between them. By changing the <code>patternContentUnits</code> attribute, we can put all the elements into the same unit system:</p>
<pre class="eval"> &lt;pattern id="Pattern" width=".25" height=".25" patternContentUnits="objectBoundingBox"&gt;
   &lt;rect x="0" y="0" width=".25" height=".25" fill="skyblue"/&gt;
   &lt;rect x="0" y="0" width=".125" height=".125" fill="url(#Gradient2)"/&gt;
   &lt;circle cx=".125" cy=".125" r=".1" fill="url(#Gradient1)" fill-opacity="0.5"/&gt;
 &lt;/pattern&gt;
</pre>
<p>Now, because the pattern content is in the same unit system as the pattern, we don't have to offset the box so that the pattern starts in the correct place, and if the object size was changed to a larger one, the pattern would automatically scale so that it had the same number of objects and repeats inside it. This contrasts with the "userSpaceOnUse" system, where if the object changes size the pattern would stay the same, and just repeat itself more times to fill the box.</p>
<p>As a slight aside, in Gecko circles seem to have trouble drawing if their radius is set to something less than 0.075 (even though they should be scaled up to have a much larger radius than that. This may be a bug in just the pattern element, or not a bug at all, I'm not sure). To work around that its probably best to avoid drawing in "objectBoundingBox" units unless you have to.</p>
<p>Neither of these uses is what one would normally think of when you think of a pattern. Patterns usually have a set size and repeat themselves independently of what an objects shape is. To create something like this, both the pattern and its contents must be drawn in the current userSpace, so that they don't change shape if the object does:</p>
<pre class="eval"> &lt;pattern id="Pattern" x="10" y="10" width="50" height="50" patternUnits="userSpaceOnUse"&gt;
   &lt;rect x="0" y="0" width="50" height="50" fill="skyblue"/&gt;
   &lt;rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)"/&gt;
   &lt;circle cx="25" cy="25" r="20" fill="url(#Gradient1)" fill-opacity="0.5"/&gt;
 &lt;/pattern&gt;
</pre>
<p>Of course, this means that the pattern won't scale if you change your object size later. All three of the above examples are shown below on a rectangle that has been slightly elongated to a height of 300px, but I should note its not an exhaustive picture, and there are other options available depending on your application.</p>
<p><img alt="Image:SVG_Pattern_Comparison_of_Units.png" class=" internal" src="/@api/deki/files/349/=SVG_Pattern_Comparison_of_Units.png"></p>
<p>{{ PreviousNext("SVG/Tutorial/Paths", "SVG/Tutorial") }}</p>
Revert to this revision