Further remarks
It is often easy to get carried away when you write about scalable vector graphics. And in the excitement of sharing one's code, it is even easy to overlook crucial details.
Case in point, a recent article on pointer events, finally solving a curious bug with a <marker> element and a host of attributes.
In the article you find an introduction to the element and a rather creative application. Unfortunately, you also find a vague note, leaving most attributes unattended.
"— there's a plethora of arguments to discover"
There are indeed many attributes, some even useful only in the context of the <marker> element. And to make justice to them, let's consider a practical scenario. Let's consider a humble, but effective, line chart.
Whether you choose to draw the line with a <path> element and a sequence of points.
<path d="M 0 4 1 3 2 3 3 1 4 4 5 3 6 3 7 2 8 0 9 1 10 1" /> Whether you prefer to structure the d attribute with the lineTo command.
<path d="M 0 4 l 1 -1 1 0 1 -2 1 3 1 -1 1 0 1 -1 1 -2 1 1 1 0" /> Whether you opt for a different element altogether and pick a <polyline> instead.
<polyline points="0 4 1 3 2 3 3 1 4 4 5 3 6 3 7 2 8 0 9 1 10 1" /> And regardless of how you separate the points with your favorite delimiter.
<polyline points="0 4, 1 3, 2 3, 3 1, 4 4, 5 3, 6 3, 7 2, 8 0, 9 1, 10 1" /> The marker element offers an immediate solution to a veritable problem: how to highlight the connections between the x, y coordinates?
You can draw additional elements on top of the line. With <circle>s, for instance, you can carefully position a few dots with the cx and cy attributes.
<circle cx="0" cy="4" r="0.15" fill="hsl(0, 0%, 28%)" />
<circle cx="1" cy="3" r="0.15" fill="hsl(0, 0%, 28%)" />
<!-- ... --> The manual approach certainly works, but the marker promises to simplify the task with a solid alternative.
Marker
The <marker> element works similarly to the all-wrapping <svg>. Add a viewBox to describe the canvas for the marker.
<marker viewBox="0 0 2 2">
<!-- ... -->
</marker> Decide how the marker should look with regular drawing elements.
<marker viewBox="0 0 2 2">
<circle cx="1" cy="1" r="1" fill="hsl(0, 0%, 28%)" />
</marker> Included in the SVG document, the element doesn’t lead to a visual.
<svg viewBox="0 0 12 7.5">
<marker viewBox="0 0 2 2">
<!-- ... -->
</marker>
</svg> It is only as you add a unique key in the id attribute.
<marker id="marker-circle" viewBox="0 0 2 2">
<!-- ... -->
</marker> That you can show its influence in specific attributes such as marker-mid.
<polyline
marker-mid="url(#marker-circle)"
points="0 4, 1 3, 2 3, 3 1, 4 4, 5 3, 6 3, 7 2, 8 0, 9 1, 10 1"
/> There are a total of three marker-related attributes, and we’ll get a chance to highlight them all, but to get started, marker-mid brings us a step from completing the task.
There’s only one issue with the current setup, and to understand the problem, focus on a single joint.
The marker starts in the right spot, precisely on the point between the segments. As with most vector graphics, however, the point describes the top left corner of the canvas, and the circle is drawn off center.
To rectify this situation you have two attributes: refX and refY.
<marker
id="marker-circle"
viewBox="0 0 2 2"
refX="1"
refY="1"
>
<!-- ... -->
</marker> The pair describes an offset relative to the viewBox, so that a value half the width, half the height is enough to shift the origin and produce the respectable graphic.
Markers
Past marker-mid, marker-start and marker-end complete the picture to highlight the ends of the line. You can repeat the reference to the same circle, but the two help to explore the syntax further, and allow me to share a quick workflow tip.
The moment you want to create a custom marker, start with an empty <svg> element and the canvas for the single drawing.
<svg viewBox="0 0 2 2">
<!-- ... -->
</svg> In this blank canvas draw the marker itself. For the one at the very beginning, we can start with a circle, perhaps the same circle we’ve used before.
<circle cx="1" cy="1" r="1" fill="hsl(0, 0%, 28%)" /> On top of the circle, we can continue with an arrow, clearly pointing to the right.
<!-- ...circle -->
<path
d="M 0.8 0.625 l 0.55 0.375 -0.55 0.375z"
fill="hsl(0, 0%, 72%)"
/> Working with a separate SVG you can test the visual as you code along. Tweak the numbers for the d attribute until the arrow looks centered; add a stroke to possibly round the edges. The possibilities at this juncture are close to endless, but for the sake of the line chart, it pays to be cautious.
Ultimately, the vector is useful as a marker, as part of a greater whole, and should not overwhelm the larger visualization. You may change the size of the graphic, and we’ll see how, but the element is also supposed to be quite small.
Once you are satisfied with the result, you just need a change in name. You no longer have an <svg>, but a <marker>.
-<svg viewBox="0 0 2 2">
+<marker viewBox="0 0 2 2">
-</svg>
+</marker> Add the necessary id, the offsets to center the piece and you are set.
<marker id="marker-start" viewBox="0 0 2 2" refX="1" refY="1">
<!-- ...circle & path -->
</marker> You are able to point to the marker and customize the start.
<polyline
marker-mid="url(#marker-circle)"
marker-start="url(#marker-start)"
points="0 4, 1 3, 2 3, 3 1, 4 4, 5 3, 6 3, 7 2, 8 0, 9 1, 10 1"
/> The marker is similar to the one for the mid-points, but detailed enough to be different. And to stress the difference, two additional attributes help to change the size: markerWidth and markerHeight.
<marker
id="marker-start"
viewBox="0 0 2 2"
refX="1"
refY="1"
markerWidth="6"
markerHeight="6"
>
<!-- ...circle & path -->
</marker> Quite reasonably, the attributes are relative to the width of the stroke, and start with a measure 3 times this value. Twice as much is enough to have the marker stand out.
And it doesn’t take much to stand out with these small touches. Repeat the process for the end of the line and the marker-end attribute — I went ahead and attempted a stylish pattern, and the chart is not only effective, but ready for prime time and the next big cycling competition. Or a more personal hiking trip.
And this speaks further to the usefulness of the element, to the flexibility afforded by the syntax.
Here you find a practical use case, a respectable, functional line chart. And to prove the concept even more, I welcome you to update the line with a new set of points. The markers will be sure to follow.
And of course there are unusual applications, like the radiant creature in the cited article. And if you need more proof, at the risk of spoiling too much, you need to look no further than the top of this very page. Behind the set of floating kites, you find only three <path> elements. Three elements with a colorful ribbon marking the points and ornate visuals marking the end.
<path
marker-mid="url(#marker-ribbon)"
marker-end="url(#marker-kite-2)"
d="M 0 0 q 4 -7 10 -5 t 10 -5 10 -5 20 -2.5"
/>