OMG, SVG Favicons FTW!

I’ve been working on some side projects recently (Style Check and bedrocss), and as with any project I work on long enough, I got to the point where I wanted to add a favicon.

I decided to play around with SVG favicons. The support is just ok (boo Safari) but it’s good enough for my needs. I’m alright if no favicon shows up on unsupported browsers. It’s not the end of the world.

By using an SVG, I’m able to get a lot of cool benefits like:

  • Crisp image quality with a single file
  • Support for emojis
  • Inline icon (no need for a linked resource)
  • Dark mode detection (sweet!)

Let’s dig into adding SVG favicons to your project. For the following examples (besides emojis), we’ll use a very basic circle SVG:

<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>
  <circle cx="50" cy="50" r="50"/>
</svg>

Adding An SVG Favicon To HTML

The syntax for adding a favicon to your website hasn’t changed in a long time, and the same applies for SVG favicons (minus the file extension).

In your HTML file’s <head> tag you place a <link> element with the rel attribute set to “icon” and the href attribute set to the path where your icon lives.

<link rel="icon" href="path/to/favicon.svg"/>

Because we are using an SVG, the icon can be whatever size you want, just make sure that the canvas is square.

If you need to search for free icons, icones is a good resource, or you can create your own with penpot.

Inlining SVG Favicons As Data-URI

After switching to SVG favicons, the first thing I tried to do was to see if I could use them with an inline format rather than linking to a separate file.

I’ve used the Data-URI trick before with inline images or backgrounds and it works like a charm. Good news, it also works for favicons.

Instead of linking to the path, prefix your entire SVG code with data:image/svg+xml;utf8, (including that last comma) and pass the whole thing to the href attribute.

<link rel="icon" href="data:image/svg+xml;utf8,<svg...>...</svg>">

I really like this method because I can just forget about placing the icon file in a folder somewhere, and I can copy/paste this code to any project (most of my side projects use the same icon now).

You could argue against using an inline SVG favicon because linking to a file can be cached, and adding the inline SVG on every page would increase the HTML size, but I don’t think it would make much difference, and I prefer the maintainability here.

If you only have one website to deal with, this may not be a big deal, but as someone that maintains several sites and uses the same favicon, this is great.

Using An Emoji For Your Favicon

A while back a tweet by Lea Verou showed how they can be used to add emojis as favicons. I probably never would have even thought of that, but it’s pretty straight forward.

The syntax works the same before. Since SVGs support text content through the <text> element and emojis are pretty much text, you can put any emoji inside your SVG (it may need some moving around to fit right).

<link rel="icon" href="data:image/svg+xml,<svg xmlns="http://w3.org/2000/svg" viewBox="0 0 100 100">
<text y=".9em" font-size="90">💩</text>
</svg>" />

(LOL, it’s poop!)

This makes it really easy to have a favicon without creating a custom one. Want something even easier? Check out emojicon.dev by Bryson Reece. It gives you a list of emojis, and you can click on any one of them to copy the whole favicon snippet to your clipboard.

If that’s nor your jam, Wes Bos also created fav.farm. It’s a 3rd party service that will generate the favicon for you. You can link directly to his service with the emoji you want.

<link rel="icon" href="https://fav.farm/💩" />

The creativity of the dev community never ceases to impress me. So many cool, smart, and creative devs out there.

Adding Dark Mode Detection

We can add a <style> tag to our SVG and use the prefers-color-scheme media query to change our icon based on the user’s dark mode preferences.

<link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>
  <style>
    svg {
      background: white;
    }
    circle {
      fill: black;
    }
    @media (prefers-color-scheme: dark) {
      svg {
        background: black;
      }
      circle {
        fill: white;
      }
    }
  </style>
  <circle cx="50" cy="50" r="50"/>
</svg>">

In this example, I’m targeting the SVG and <circle> directly, but you could just as well use classes. For custom SVGs, you’ll probably need to do that.

The <style> tags in the SVG are contained within that XML document, so you don’t have to worry about styles leaking into the rest of your application.

Thank you so much for reading. If you liked this article, please share it, and if you want to know when I publish more articles, sign up for my newsletter or follow me on Twitter. Cheers!

Originally published on austingil.com.

19