aboutsummaryrefslogtreecommitdiff
path: root/_tils/2020-12-29-svg-favicon.md
blob: 54cca9ab1729c64dd4b56308cb4f1b3a964735e5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
---

title: SVG favicon

date: 2020-12-29

updated_at: 2021-01-12

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
(at [`/static/lord-favicon.svg`](/static/lord-favicon.svg)) 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/lord-favicon.png %}`, otherwise
the file would be considered missing.