Appearance
Sometimes, I've had the need to embed an icon inline in a page. This might be not something I'd generally advise, but there are times when it's interesting.
One approach is using base64 encoding to include the image in the page.
However, the mix of encodings makes the result messy, not as compressible and not very visually understanable or editable.
This is where SVGs make a very good fit, specially in those situations where we just need a very simple icon without a lot of detail.
Below I'll show some ways to create simple SVG files. They are "small" in the sense of taking relativelly few space in the code, but being scalable they can match any size.
Emoji-based SVG icons ​
Possibly the smallest SVG expression you can make that still packs enough meaning to add some distinctiveness is using a <text>
tag to simply use an emoji as the SVG image.
Of course this has some drawbacks, like how the look and feel would entirelly depend on the emoji font that was used to generate the SVG. But if you just want a quick, simple and recognizable image icon, while also taking a tiny amount of space suitable for inline embedding, you can use an expression as below:
xml
<svg xmlns='http://www.w3.org/2000/svg' height='20' width='20'><text y='15' font-size='16'>🎓</text></svg>
Or, within an img tag:
xml
<img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='20' width='20'><text y='15' font-size='16'>🎓</text></svg>"/>
Resulting in a tiny icon like the one below, which might be fine for a small favicon:
Below a description of each attribute:
- The
<svg>
tag is used to indicate this is an SVG (official documentation)xmlns='http://www.w3.org/2000/svg'
: this attribute is mandatory to indicate the SVG specification. If you are inlining the SVG element inside of an HTML page, this would not be required. But if you are encoding the file as adata:
URL (like we have done in theimg
tag in the example), not specifying this attribute will result in an error like this:height='20'
: sets the height of the SVG to 20 unitswidth='20'
: sets the width of the SVG to 20 units
- The
<text>
is used to introduce text inside the SVG (official documentation)y='15'
: Y position. By default it'll use the origin (x=0 y=0), but this will place the text outside of the image, since it's placed directly on top of the writting row line, so we have to lower the text a bit (incresing the Y coordinate lowers it, while increasing X moves to the right).font-size='16'
: this will define the font size of the text. This is necessary because the default value for the font-size might be different depending on the browser/viewer configuration.
While defining a fixed height
and width
within the SVG tag might be desirable when you want your SVG to be of a certain size, one of the advantages of SVG is its scalability, so in many cases you might want it to be able to adapt to the container, or just fill the space available following CSS rules or any other constraints.
We can allow the SVG to scale by defining a viewBox
instead of setting fixed height
/ width
. The viewbox will describe the box that will be used as a "camara" content outside that box will be cropped, and a smaller box will zoom in or magnify the content inside, while a bigger one will zoom out. This will allow the SVG to change size according to whatever CSS rules are set in the webpage.
xml
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><text y='14'>🎓</text></svg>
We can then set some constraint, like adding the svg to a img
tag with a fixed width
.
<img width="300" src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><text y='15' font-size='16'>🎓</text></svg>"/>
This will result in the image below:
If you open that image in a separate tab (you may copy this link and open it... but most browser might not allow to click it directly) you'll see how the svg actually expands to fit the browser boundaries.
You'll also notice the icon isn't perfectly centered. We could center it by further tweaking the x
and y
attributed from <text>
, but instead we could just adjust the viewBox and avoid adding any coordinates to the text element, which should simplify things and minimise its size (we'll still need the font-size
though):
xml
<svg viewBox='2 -14.5 18 18'><text font-size='16'>🎓</text></svg>
Notice that the values can be decimal at any point, SVG being scalable supports precise dimensions.
Also, for simplicity, I've excluded the xmlns
attribute, because I'm loading it as an SVG HTML element, but remember that loading it in any other way will require it.
xml
Bad: <img width="100" src="data:image/svg+xml;utf8,<svg viewBox='2 -14.5 18 18'><text font-size='16'>🎓</text></svg>"/>
Good: <img width="100" src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='2 -14.5 18 18'><text font-size='16'>🎓</text></svg>"/>
Bad: Good:
Polygonal shapes ​
Another way we can make a lightweight SVG is by creating simple shapes by just joining a set of a few dots.
For this we would need to think in our head (or draw in some paper) the coordinates of each of the points we want.
The values we set in the viewBox
parameter would represent the minimum and maximum values for x and y. Then the element polygon
can be used with a points
field containing a space separated list of 2D coordinates which define the list of points in order.
The expression below would draw a simple black triangle:
xml
<svg viewBox='0 0 10 10'>
<polygon points="5,1 9,9 1,9"/>
</svg>
We can further complicate this with additional points as well as defining a style
field where to set the colors for filling the polygon as well as the outline stroke color and width.
For example, below is a colorful zig-zag shape made with 6 dots.
xml
<svg viewBox='0 0 10 10'>
<polygon points="6,1 9,6 4,6 4,9 1,4 6,4" style="fill:yellow;stroke:darkgreen;stroke-width:0.5" />
</svg>
You can also combine the text
element with a polygon
, like in the example below:
xml
<svg viewBox='0 0 40 40'>
<polygon points='10,1 30,1 39,10 39,30 30,39 10,39 1,30 1,10' style='fill:red;stroke:white;stroke-width:1' />
<text x='7' y='28' font-size='20' font-family='Impact' style='fill:white'>No!</text>
</svg>
Rotating animation ​
SVGs support animations too! for something like a loading spinner, we can introduce a rotating animation.
We can rotata a polygon
element by adding inside of it a children animateTransform
object with type
"rotate" and a from
and to
fields describing the initial and final angles and centers of rotation, with dur
describing the duration of each animation cycle.
Below an example on how this can be done.
xml
<svg viewBox='5 5 30 30'>
<polygon points='12,10 28,10 22,20 28,30 12,30 18,20' style='fill:#999;stroke:black;stroke-width:2;stroke-linejoin: round' >
<animateTransform
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 20 20"
to="360 20 20"
dur="5s"
repeatCount="indefinite" />
</polygon>
</svg>