aboutsummaryrefslogblamecommitdiff
path: root/_tils/2020-12-29-svg-favicon.md
blob: 42d17fabe1066194674fc7a859e76526eb57ef33 (plain) (tree)



























































































































                                                                                   
---
title: SVG favicon
date: 2020-12-29
layout: post
lang: en
ref: svg-favicon
---

I've wanted to change this website's favicon from a plain `.ico` file to a
proper SVG. The problem I was trying to solve was to reuse the same image on
other places, such as avatars.

Generating a PNG from the existing 16x16 icon was possible but bad: the final
image was blurry. Converting the `.ico` to an SVG was possible, but sub-optimal:
tools try to guess some vector paths, and the final SVG didn't match the
original.

Instead I used a tool to draw the "vector pixels" as black squares, and after
getting the final result I manually cleaned-up the generated XML:

```xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
  <path d="M 0  8  L 1  8  L 1  9  L 0  9  L 0  8  Z" />
  <path d="M 0  13 L 1  13 L 1  14 L 0  14 L 0  13 Z" />
  <path d="M 1  8  L 2  8  L 2  9  L 1  9  L 1  8  Z" />
  <path d="M 1  13 L 2  13 L 2  14 L 1  14 L 1  13 Z" />
  <path d="M 2  8  L 3  8  L 3  9  L 2  9  L 2  8  Z" />
  <path d="M 2  13 L 3  13 L 3  14 L 2  14 L 2  13 Z" />
  <path d="M 3  8  L 4  8  L 4  9  L 3  9  L 3  8  Z" />
  <path d="M 3  13 L 4  13 L 4  14 L 3  14 L 3  13 Z" />
  <path d="M 4  7  L 5  7  L 5  8  L 4  8  L 4  7  Z" />
  <path d="M 4  8  L 5  8  L 5  9  L 4  9  L 4  8  Z" />
  <path d="M 4  13 L 5  13 L 5  14 L 4  14 L 4  13 Z" />
  <path d="M 5  6  L 6  6  L 6  7  L 5  7  L 5  6  Z" />
  <path d="M 5  7  L 6  7  L 6  8  L 5  8  L 5  7  Z" />
  <path d="M 5  13 L 6  13 L 6  14 L 5  14 L 5  13 Z" />
  <path d="M 6  5  L 7  5  L 7  6  L 6  6  L 6  5  Z" />
  <path d="M 6  6  L 7  6  L 7  7  L 6  7  L 6  6  Z" />
  <path d="M 6  14 L 7  14 L 7  15 L 6  15 L 6  14 Z" />
  <path d="M 7  1  L 8  1  L 8  2  L 7  2  L 7  1  Z" />
  <path d="M 7  14 L 8  14 L 8  15 L 7  15 L 7  14 Z" />
  <path d="M 7  15 L 8  15 L 8  16 L 7  16 L 7  15 Z" />
  <path d="M 7  2  L 8  2  L 8  3  L 7  3  L 7  2  Z" />
  <path d="M 7  3  L 8  3  L 8  4  L 7  4  L 7  3  Z" />
  <path d="M 7  4  L 8  4  L 8  5  L 7  5  L 7  4  Z" />
  <path d="M 7  5  L 8  5  L 8  6  L 7  6  L 7  5  Z" />
  <path d="M 8  1  L 9  1  L 9  2  L 8  2  L 8  1  Z" />
  <path d="M 8  15 L 9  15 L 9  16 L 8  16 L 8  15 Z" />
  <path d="M 9  1  L 10 1  L 10 2  L 9  2  L 9  1  Z" />
  <path d="M 9  2  L 10 2  L 10 3  L 9  3  L 9  2  Z" />
  <path d="M 9  6  L 10 6  L 10 7  L 9  7  L 9  6  Z" />
  <path d="M 9  15 L 10 15 L 10 16 L 9  16 L 9  15 Z" />
  <path d="M 10 2  L 11 2  L 11 3  L 10 3  L 10 2  Z" />
  <path d="M 10 3  L 11 3  L 11 4  L 10 4  L 10 3  Z" />
  <path d="M 10 4  L 11 4  L 11 5  L 10 5  L 10 4  Z" />
  <path d="M 10 5  L 11 5  L 11 6  L 10 6  L 10 5  Z" />
  <path d="M 10 6  L 11 6  L 11 7  L 10 7  L 10 6  Z" />
  <path d="M 11 6  L 12 6  L 12 7  L 11 7  L 11 6  Z" />
  <path d="M 11 8  L 12 8  L 12 9  L 11 9  L 11 8  Z" />
  <path d="M 10 15 L 11 15 L 11 16 L 10 16 L 10 15 Z" />
  <path d="M 11 10 L 12 10 L 12 11 L 11 11 L 11 10 Z" />
  <path d="M 11 12 L 12 12 L 12 13 L 11 13 L 11 12 Z" />
  <path d="M 11 14 L 12 14 L 12 15 L 11 15 L 11 14 Z" />
  <path d="M 11 15 L 12 15 L 12 16 L 11 16 L 11 15 Z" />
  <path d="M 12 6  L 13 6  L 13 7  L 12 7  L 12 6  Z" />
  <path d="M 12 8  L 13 8  L 13 9  L 12 9  L 12 8  Z" />
  <path d="M 12 10 L 13 10 L 13 11 L 12 11 L 12 10 Z" />
  <path d="M 12 12 L 13 12 L 13 13 L 12 13 L 12 12 Z" />
  <path d="M 12 14 L 13 14 L 13 15 L 12 15 L 12 14 Z" />
  <path d="M 13 6  L 14 6  L 14 7  L 13 7  L 13 6  Z" />
  <path d="M 13 8  L 14 8  L 14 9  L 13 9  L 13 8  Z" />
  <path d="M 13 10 L 14 10 L 14 11 L 13 11 L 13 10 Z" />
  <path d="M 13 12 L 14 12 L 14 13 L 13 13 L 13 12 Z" />
  <path d="M 13 13 L 14 13 L 14 14 L 13 14 L 13 13 Z" />
  <path d="M 13 14 L 14 14 L 14 15 L 13 15 L 13 14 Z" />
  <path d="M 14 7  L 15 7  L 15 8  L 14 8  L 14 7  Z" />
  <path d="M 14 8  L 15 8  L 15 9  L 14 9  L 14 8  Z" />
  <path d="M 14 9  L 15 9  L 15 10 L 14 10 L 14 9  Z" />
  <path d="M 14 10 L 15 10 L 15 11 L 14 11 L 14 10 Z" />
  <path d="M 14 11 L 15 11 L 15 12 L 14 12 L 14 11 Z" />
  <path d="M 14 12 L 15 12 L 15 13 L 14 13 L 14 12 Z" />
</svg>
```

The good thing about this new favicon is that a) it is simple enough that I feel
comfortable editing it manually and b) it is an SVG, which means I can generate
any desired size.

With the new favicon file, I now had to add to the templates' `<head>` a
`<link>` to this icon:
```html
<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
  ...
```

Still missing is a bitmap image for places that can't handle vector images. I
used Jekyll generator to create an PNG from the existing SVG:

```ruby
module Jekyll
  class FaviconGenerator < Generator
    safe true
    priority :high

    SIZE = 420

    def generate(site)
      svg = 'static/favicon.svg'
      png = 'static/favicon.png'
      unless File.exist? png then
        puts "Missing '#{png}', generating..."
        puts `inkscape -o #{png} -w #{SIZE} -h #{SIZE} #{svg}`
      end
    end
  end
end
```

I had to increase the priority of the generator so that it would run before
other places that would use a `{% link /static/favicon.png %}`, otherwise the
file would be considered missing.