When I first set this site up I used this technique to add a favicon with the 🥶 (cold face) emoji. This was a great way to have a favicon present without having to stress about designing one, or resorting to my usual default of a black square 🥱. Good enough for now, I thought, I can worry more about it later.
Here’s the code I used for that.
<link rel="shortcut icon" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20100%20100%22%3E%3Ctext%20y%3D%22.9em%22%20font-size%3D%2290%22%3E%F0%9F%A5%B6%3C%2Ftext%3E%3C%2Fsvg%3E" type="image/svg+xml">
That was fine until I noticed that a search result for my site in DuckDuckGo (my primary search engine at time of writing) didn’t support emojis as a shortcut icon. I think partially because it (or Bing or whichever system it uses for it) tries to generate a small self-hosted image for the short cut icon. Drat. Time to do something about it.
I still didn’t really want to have to design anything. I can tackle that later if I ever get around to seriously thinking about the visual identity of this site. For now I wanted a small improvement, a kaizen if you will. So I thought about whether it was possible to get raw SVG versions of emoji. In my search I came across OpenMoji which I’d seen mentioned before. It provides open source versions of emoji that are available as coloured or outlined SVG files. Perfect!
I decided to switch from 🥶 (cold face) to 👾 (space invader/alien monster) as I really liked the image by Antonia Wagner, and it worked well in outline. I decided to go for outline so that I didn’t have to commit to a colour. I also wanted to implement dark mode support to the SVG and I though it would make doing that simpler.
Dark mode support #
Adding dark mode support was pretty simple. First I replaced all hardcoded colour references to currentColor
so I could control the colour more reliably through CSS. eg.
- <rect ... stroke="#000000" ... />
+ <rect ... stroke="currentColor" ... />
Then I added some CSS in the body of the SVG file by using a <style>
tag inside a <defs>
tag. That CSS simply applied a black stroke to all the visual elements in the SVG, and using an @media
rule, switched that to white when a visitor is in dark mode.
<svg ... >
<defs>
<style>
rect, path, line, polyline {
stroke: black;
color-scheme: light dark;
}
@media (prefers-color-scheme:dark) {
rect, path, line, polyline {
stroke: white;
}
}
</style>
</defs>
...
</svg>
That’s it! And here’s the cute little critter in all its dark-mode-detecting glory.
And here’s the code in full.
<svg id="emoji" viewBox="0 0 72 72" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
rect, path, line, polyline {
stroke: black;
color-scheme: light dark;
}
@media (prefers-color-scheme:dark) {
rect, path, line, polyline {
stroke: white;
}
}
</style>
</defs>
<g id="line">
<rect x="25.175" y="31" width="3.6" height="6" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="22,45 16,45 16,39"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="22.583,25 22.583,20 26,20"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="48.708,25 48.708,20 45.292,20"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="13,35 10,35 10,20 16,20 16,35"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="56,35 56,20 62,20 62,35 59,35"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="26,20 26,14 32,14 32,20"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="39,20 39,14 45,14 45,20"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="16,35 19,35 19,38 13,38 13,35"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="59,35 59,38 53,38 53,35 56,35"/>
<rect x="16" y="51" width="6" height="6" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<rect x="50" y="51" width="6" height="6" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="28,45 28,51 22,51 22,45"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="50,45 56,45 56,39"/>
<polyline fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" points="44,45 44,51 50,51 50,45"/>
<rect x="43.425" y="31" width="3.6" height="6" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M44,45L44,45z"/>
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M39,20L39,20z"/>
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16,25L16,25z"/>
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M49,25L49,25z"/>
<line x1="28" x2="44" y1="45" y2="45" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<line x1="32" x2="39" y1="20" y2="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<line x1="16" x2="22" y1="25" y2="25" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<line x1="49" x2="56" y1="25" y2="25" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
</svg>
And here’s the code I needed to add to the head. As I was switching to using an external SVG file I noticed that I needed to add the sizes="any"
to get it to show up properly.
<link rel="shortcut icon" href="/public/alien.svg" type="image/svg+xml" sizes="any">
All in all, a neat little way to get a dark mode supporting favicon!