Skip to content

Writting tiny SVGs

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 a data: URL (like we have done in the img 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 units
    • width='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>
No!

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>

Personal page