Thin, looping strokes against a black background

Arrows, dotted lines and dashes are extremely useful for diagrams and illustrations in . Tools like and Inkscape can add these decorations, but it’s useful to know how to add and adjust them manually. In this article, I’ll concentrate on strokes:

Basic Attributes

The appearance of a path is controlled with stroke (the color of the path, defined using any CSS color system) and stroke-thickness (assumed to measure pixels, although any CSS measurement system supported by SVG can be used).

Dashes

Strokes are provided with a dashes via the stroke-dasharray attribute. Values are applied in the order of dash and gap; unitless numbers are assumed to be pixels, although the values could be specified in any units SVG understands (most commonly, percentages). Single values are assumed to be the same value for both dash and gap:

Given a line:

<svg viewBox="0 0 300 10">
    <line x1="0" y1="0" x2="300" y2="0" 
	stroke="black" stroke-width="10"  stroke-dasharray="5" />
</svg>

Which creates:

Those presentation attributes and values can be expressed in CSS to achieve the same result:

<svg viewBox="0 0 300 10">
<defs>    
    <style>
        line#es {
            stroke: black;
            stroke-width: 5;
            stroke-dasharray: 5;
        }
    </style>
</defs>    
    <line id="es" x1="0" y1="0" x2="300" y2="0" />
</svg>

If there are pairs of numbers for stroke-dasharray, the second number in each pair denotes the gap:

line {
        stroke: black;
        stroke-width: 5;
        stroke-dasharray: 5, 20;
}

If the attribute value count is odd, the values are repeated to make them even, so 5, 20, 5 renders as:

“Read” from left to right on the line above, these stroke-dasharray values would be described as: “dash of 5, space of 20, dash of 5; space of 5, dash of 20, space of 5”.

stroke-dashoffset

The stroke-dashoffset presentation attribute determines where the stroke starts; with a dash offset, it pushes the start “further into” the line:

line#dashstart {
    stroke: black;
    stroke-width: 5;
    stroke-dasharray: 5, 20, 5;
    stroke-dashoffset: 20;
}

Animating Strokes

It’s also possible to animate SVG stroke in CSS. If the stroke-dashoffset has the same value as stroke-dasharray and the length of the path itself; the stroke is essentially “pushed off” the visible end of the path. We can then animate this by changing stroke-dashoffset to 0 over time:

@keyframes strokeanim {
    to { stroke-dashoffset: 0; }
}
line#dashstart {
    stroke: hsl(260, 50%, 30%);
    stroke-width: 15;
    stroke-dasharray: 300;
    stroke-dashoffset: 300;
    animation: strokeanim 2s alternate infinite;
}

Which produces:

The difficult part of this is usually determining the exact length of the path, and therefore the correct values for stroke-dasharray and stroke-dashoffset, which why it’s usually accomplished with … which I’ll cover in an upcoming article.

Other Uses of Stroke

While this article has used lines for stroke examples for the sake of clarity and simplicity, strokes can be applied to any SVG basic shape, including polygons, polylines and paths. For example, it’s very easy to recreate visual effect of Adobe PhotoShop’s marquee selection tool with a <rect> element and the CSS we have learnt so far:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 200">
<style type="text/css">
rect#strokedrect {
    stroke: hsl(260, 50%, 3%);
    fill: white;
    stroke-width: 7;
    stroke-dasharray: 10;
}
</style>
    <rect id="strokedrect" x="0" y="0" width="300" height="200" />
</svg>

Which creates:

Note that strokes are always drawn in the “mid-point” of the assumed path. In the examples so far, this hasn’t been an issue, as the elements were always the same size as their viewBox containers, and/or have a “transparent” fill. However, it can be a very real problem if either of these conditions is not true. For example, if the rectangle is drawn slightly inside the viewBox and given a colored fill:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 200">
<style type="text/css">
rect#oddstrokedrect {
    stroke: hsl(260, 50%, 3%);
    fill: grey;
    stroke-width: 12;
    stroke-dasharray: 15;
}
</style>
    <rect id="oddstrokedrect" x="20" y="20" width="260" height="160" />
</svg>

Which creates:

It’s entirely possible to animate this stroke as well:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 200">
<style type="text/css">
@keyframes marchingants {
    to { stroke-dashoffset: 19; }
}
rect#strokedrect {
    stroke: hsl(260, 50%, 90%);
    fill: white;
    stroke-width: 7;
    stroke-dasharray: 10;
    animation: marchingants 1s forwards infinite linear;
}
</style>
    <rect id="strokedrect" x="0" y="0" width="300" height="200" />
</svg>

Creating:

Conclusion

There are many more possibilities for advanced uses of SVG stroke and markers, as hinted in the introduction, which I’ll be looking at in the next article.

Photograph by Chris Searle, licensed under Creative Commons

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.