A view outside
You might have seen one way to set up an icon system already. One <svg> with many <symbol> elements, each with its own, unique id.
<svg style="position: absolute; width: 0; height: 0">
<symbol id="glyph-0"><!-- ... --></symbol>
<!-- ... -->
</svg> Add the node in the page and include the icons by reference, with the <use> element and on a need to have basis.
<svg viewBox="0 0 1 1">
<use href="#glyph-0" />
</svg> The solution works wonders to style paragraphs, buttons, or any content you might want to decorate, but it’s certainly not the only one. And to gain some perspective, it helps to consider an alternative. Always with vectors, with SVG syntax, but also with a robust <img> tag.
One vector
Let’s start with the design of a few icons. And do not worry, this time I will spare you the details of the syntax itself. There is a time for everything, and in this instance it is better to keep our focus on the task at hand.
Suffice it to say, behind the icons you find a few <path> elements nested in one, large <svg>.
<svg viewBox="0 0 600 100">
<!-- ... -->
</svg> The icons sit side by side and you see each and every one of them. Conveniently, and by design, they share one more trait: they occupy the same space, the same square figure.
You may argue the visuals don’t stretch to fill the boxes, but they are not meant to. And I challenge you to create a consistent rhythm, a cohesive set where the different icons share the same space.
The point stands. In the first square you see the first icon. Move 100 units right to focus on the sibling figure. And in doing so, you’ve just found out how to set up the icon system. Manually at least.
One image
Save your one vector in an .svg file. The only attribute I stress you should add is xmlns — you’ll thank me later for the inclusion of these characters.
-<svg viewBox="0 0 600 100">
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 100"> You might be used to have SVG syntax in the markup — this website is certainly fond of the practice, but it is equally possible to add vector graphics as an image with the dedicated <img> element.
<img
src="icons.svg"
alt="Data visualizations galore: bar chart, line chart, and a handful more."
width="600"
height="100"
/> There are four attributes you should always remember. src points to the file, its accurate location, while alt gives a string to support the piece. It certainly won’t happen, but in the moment the image fails, in the moment there’s no picture to show off, the text works as a helpful backup.
Two more attributes complete the tag: width and height. The values are liable to conflict with the aspect ratio of the vector graphic, and we’ll see how, but are essential to have the browser lay out the page from the get-go. Even before the image is loaded, the browser knows to reserve the necessary space.
And that’s it, point to the resource and the icons appear in full, almost as in the beginning of this article.
xmlns? This is where the attribute proves its worth. Forget to specify the namespace and the image fails. The good news is you’ll see the alt text in its place. And you have a jumbled sequence of characters to express your surprise.
Jokes aside, remember the namespace and, holding off on a few drawbacks, you can now implement the promised icon set. In at least two ways.
The first one comes in the form of the <view> element, and asks you to update the SVG syntax ahead.
In the document, you anticipate a view, a window of the larger graphic with a distinct id.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 100">
<view id="bar-chart" />
<!-- ... -->
</svg> You decide what to show with a new viewBox attribute.
<view id="bar-chart" viewBox="0 0 100 100" /> You are essentially updating the viewBox from the original value. Configure the views for the different icons.
<view id="bar-chart" viewBox="0 0 100 100" />
<view id="pie-chart" viewBox="400 0 100 100" /> And you now have a choice, a few options. To show the icons, the full set, refer to the graphic as-is. To show one icon, and only one, update the reference, pointing to the view through the unique ID.
<img
src="icons.svg#pie-chart"
alt="A debatable pie chart."
width="200"
height="200"
/> You zoom in on the graphic, and you find the desired sprite.
Hold your suspicions a tad longer. There are a few issues worth noting. Before we get there, however, it is useful to illustrate the second way to view the sprites.
Outside of the <view> element, you are able to focus on parts of the graphic yourself, directly in the src attribute. Instead of pointing to the entire image.
<img
src="icons.svg"
...
/> Instead of accepting the default viewBox, the idea is to specify the attribute with a fitting syntax.
<img
src="icons.svg#svgView(viewBox(200 0 100 100))"
alt="An teaching candlestick chart."
width="200"
height="200"
/> A view without a <view> element.
A few hiccups
Included as an image SVG becomes quite more rigid. Anda it wouldn’t be fair not to point out a couple of issues with the current setup.
Immediately, and with evidence, currentColor. In the markup, add the value to the fill or the stroke of the shapes and you are able to change the color on a whim.
svg {
color: tomato;
} As an image, you are not able to extend the same feat, and you are stuck with a default, bleak black look.
Then again, and I hinted at the problem with the dimensions of the shape, aspect ratio . Vector graphics being scalable, you are able to have them grow and shrink at a moment’s notice.
svg {
width: 2em;
height: 2em;
} Through the width and height attributes, through the width and height properties, the graphic scales to respect the aspect ratio set with the viewBox attribute.
As an image, you can very well change the size. And you’ve already seen how for the icons.
<img
src="icons.svg#pie-chart"
alt="A debatable pie chart."
width="200"
height="200"
/> In this instance the width and the height are fixed to 200 pixels, and the image scales to perfection.
Mess up the aspect ratio though, try an image thrice as wide as it is tall, and something will definitely not escape your eyes.
Yes, you see the icon, but surrounded by its two neighbors. A view acts as a zoom, a point of view for the larger graphic. It does not work to clip the area for the icon itself. As you scale the visual to the improper measure, the SVG grows as wide and tall as it possibly can, and the sibling icons come back in the spotlight.
If you are thinking “well, even with these issues, I know of a new way to set up an icon system”, I’m glad you accepted the information.
If you are thinking “wait, beyond these issues, there’s no reason I can’t combine the syntax with the <picture> element and pick and choose what to show”. “I add a large version in a regular <img> element”.
<picture>
<img
src="picture.svg"
alt="A vision of a quiet afternoon. How you interpret it depends on your preference, on your point of view."
width="800"
height="600"
/>
</picture> “In the <source> element then, I point to a portion of the graphic with a view”.
<picture>
<source srcset="picture.svg#window" width="500" height="500" />
<img ... />
</picture> “I instruct the browser to show the version in the srcset attribute with a specific condition, say a maximum size for the viewport”.
<source media="(max-width: 600px)" srcset="picture.svg#window" width="500" height="500" /> “And there, different images for different screen sizes”.
Well, I’m thrilled not to be the only one with often far-fetched thoughts. And I am left wondering, whether you are currently appreciating the decor or dreaming about the world outside.
You certainly wouldn’t dare to resize the page to have it all.