Table of contents
Revision history (last updated )
- Linked out to Masa Kudamatsu’s article and put the newest hottest markup pattern up top
I saw this useful article from Evil Martians about chopping down the number of files needed for favicons (the little icons in browser tabs and bookmarks) and other site identification images, especially with the semi-recent support of SVG favicons.
I’ve had to swap out the favicons for two sites lately. Although I found that article’s advice generally accurate, I found some complications with their suggestions.
Update!
30 December 2021: Hoo-eee there’s been some discoveries here!
Twitter user @subzey (via CSS Tricks) figured out the secret sauce to make Chrome do what we want:
<!-- For browsers that don't support .svg favicons (pretty much just Safari right now): -->
<link rel="icon" href="/favicon.ico" sizes="any" />
<!-- For browsers that DO support SVG favicons (most of them now): -->
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
The trick is sizes="any"
on the first favicon.ico link. Then Chrome will only download and use the .svg
version that comes after.
Although that takes the wind out of half of my complaints here, I’m going to leave this article up as originally written.
If you’re looking for the definitive way to handle favicons-and-such these days, Masa Kudamatsu’s more recent and extraordinarily well-researched article is where I’d start.
My original article follows:
Chrome will prefer a .ico icon over a .svg
Say you’ve got this markup as recommended by that Evil Martians article:
<link rel="icon" href="/favicon.ico" />
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
In my testing, Chrome will load the favicon.ico
, not the SVG file. That’s probably OK, but if you were banking on the SVG for the ability to change colors during dark mode, the favicon.ico
is no good.
This has been reported as a bug, but looking at the comments there it might not be strictly a bug, because .ico
files typically contain a few different sizes of icons, one of which might be exactly the size the browser needs at that moment, so Chrome thinks that’s a great thing to use even if there’s a perfectly flexible .svg
available.
A workaround is to drop the link to /favicon.ico
and replace it with a .png
version of your icon (32×32 pixels should be OK).
<link rel="icon" href="/icon.png" type="image/png" />
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
Given that, Chrome should prefer the .svg
over the .png
, as will Firefox. Be careful not to provide any sizes
attributes that might nudge Chrome one way or the other.
Do leave favicon.ico
at the root of your site, as some browsers and services will only look there.
You would think you could drop the link to the .png
completely (leaving only the .svg
), but…
Safari does not fully support .svg icons
If you have only this:
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
…you won’t get a favicon on macOS Safari. Safari as of this writing supports SVG icons, but only single-color ones via the non-standard rel="mask-icon"
:
<link rel="mask-icon" href="/favicon.svg" color="#990000" />
I came away from the Evil Martians article thinking that Safari was good to go with SVG icons:
Safari used to have a separate requirement to display an icon in pinned tabs. However, since Safari 12, we can use a regular favicon for pinned tabs. Even apple.com doesn’t use the mask-icon anymore.
That is technically correct! But apple.com, as of this writing, has absolutely no markup for any favicon. They have a a /favicon.ico
file and nothing else—the old fashioned thing that still works everywhere.
Anyway, Safari still supports rel="mask-icon"
and it appears to choose that over other options. The linked .svg
file must be a single color, and Safari will overlay that with the color
attribute that you provide.
You don’t get any support for changing styles in media queries like @media (prefers-color-scheme: dark)
. If the color
is on dark side and you’re in Dark Mode, Safari will put a light background underneath it to increase the contrast; you can’t control this at all.
If you need more than one color in your icon, Safari will use a referenced .png
icon just fine, so you can skip the rel="mask-icon"
.
So, for the favicons, you want a favicon.ico
at the root of your site and this HTML markup:
<!-- For browsers that don't support .svg favicons (pretty much just Safari right now): -->
<link rel="icon" href="/icon.png" type="image/png" />
<!-- For browsers that DO support SVG favicons (most of them now): -->
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
<!-- A special SVG for Safari assuming a single color is OK: -->
<link rel="mask-icon" href="/safari-mask-icon.svg" color="#990000" />
The Wikipedia article on Favicons has an accurate table of format support and how different browsers use them that was hugely useful in figuring this out.
Lighthouse demands “maskable” Android icons
I caught this in a Lighthouse audit: you’ll get an error if none of the icons
in your manifest are flagged as being "maskable"
. I had to look it up but apparently different flavors of Android will need an icon with enough padding to get cropped in a variety of squircles or blobbies or however the platform shapes app icons.
There’s a web app where you can upload an icon, resize it, check how it fits in several of the known masks, then export it.
Once you have a suitable file, you can link to it in your manifest file with "purpose": "maskable"
:
// manifest.webmanifest
{
"icons": [
{ "src": "/192.png", "type": "image/png", "sizes": "192x192" },
{ "src": "/512.png", "type": "image/png", "sizes": "512x512" },
{
"src": "/android-maskable-192.png",
"type": "image/png",
"sizes": "192x192",
"purpose": "maskable"
}
]
}
While you’re in there, Lighthouse will also complain if your manifest doesn’t also have these properties:
name
: the name of your siteshort_name
: a shorter name if space is tightbackground_color
: the background color of the splash screentheme_color
: the color app toolbars will bedisplay
: how much browser controls should be visible? The default is"browser"
.
Clearing the icon cache in macOS Safari is deeply unpleasant
If you’re trying to test any changes in favicons, Safari caches them aggressively and does not give you an easy way to purge that cache. Nothing I found online totally worked. Several places like this Macworld article tell you about one system folder that you have to clear out.
But that didn’t work for me.
The problem is there isn’t one, but three system folders you have to clear out. Here’s what worked for me:
- Quit Safari.
- In Finder, Go > Go to Folder….
- Enter
~/Library/Safari/Favicon Cache/
. - Select everything there and move it to Trash.
- Do the same for
~/Library/Safari/Touch Icons Cache/
. This is where Safari keeps icons for Favorites listings on the “New tab” page. - Do the same for
~/Library/Safari/Template Icons/
. This is anyrel="mask-icon"
s Safari is using. This was the missing link for me. Safari never seems to want to let these go. I had some local development URLs that were showing icons from years ago and they would never update. - Empty the Trash.
- Open Safari again.
That should do it. I don’t think there are any guarantees here, but that worked for me in my testing.