Hacker News new | past | comments | ask | show | jobs | submit login
SVG favicons have some cool benefits (austingil.com)
197 points by feross on July 7, 2021 | hide | past | favorite | 73 comments



Complex SVG Favicons will usually be larger in term of bytes than highly compressed PNG icons. We did an extensive study of Favicons served on the top 500 websites [1].

If you want to stick with the old-school PNG icons, we open-sourced `icopack` - our internal tool for efficient packing of individual PNGs into a highly-optimised ICO files [2].

[1] https://optidash.ai/blog/optimizing-favicons-for-the-worlds-...

[2] https://github.com/optidash-ai/icopack


> Complex SVG Favicons will usually be larger in term of bytes than highly compressed PNG icons.

The post you linked to doesn't include the word "SVG". Is there a separate article that compares using one SVG file vs. using multiple images?

It's hard to imagine that using a typical suite of PNG images at different sizes is going to be more efficient (and future-proof) than a single SVG file run through svgo.


> It's hard to imagine that using a typical suite of PNG images at different sizes is going to be more efficient (and future-proof) than a single SVG file run through svgo.

That's the wrong comparison though - each browser will typically only download one favicon size.


Great article

Earlier this year I created my own ICO editor for fun [1]. I learned a lot about reading and writing binary files, and decoding BMP data. While testing the editor on existing site favicons I kept finding that they were all uncompressed BMP data, and came to a similar conclusion to your article after checking the icons used on the Alexa top 100 sites.

I guess this is a combination of the ICO format being somewhat opaque (it's hard to tell if it's using BMP or PNG without using a hex editor), and that there aren't many applications available that create PNG-based ICO files in the first place (especially ones that are used in web development pipelines).

1. https://ico-editor.lach.app/ - Client-side ICO viewer/editor, can open and convert BMP to PNG.

PS. I noticed that your own site's favicon is uncompressed.


PNG support in .ico files was introduced in Windows Vista and I expect Internet Explorer just supports whatever the OS does. There might still be holdovers (both sites and tools) from when people cared about XP support.


Thank you for this. Hope this becomes standard practice.


People keep on talking about (prefers-color-scheme: dark), but it isn’t what they want it to be—never has been, and probably never will be (though I will admit that prefers-color-scheme could theoretically be special-cased for favicon rendering).

For example, in Firefox, I use the dark theme for the UI, but that’s completely unrelated to the content, and prefers-color-scheme matches the content, not the chrome. Content I keep normal, light.

It’s quite possible (not uncommon, even) for the active tab to have a light background and inactive tabs to have a darker background. (A decade ago, this is what would happen by default on the default Windows XP theme, though it was the XP blue rather than anything dark dark.)

Or Chromium: like Firefox, it has themes; but beyond that, incognito window chrome gets a dark background.

Admittedly, (prefers-color-scheme: dark) matching makes it almost certain that you’re rendering against a dark background of some form, but it not matching tells you absolutely nothing about the background.

The fact of the matter is that your favicon could be rendered against absolutely any colour, and you need to make sure your icon will work on very light colours and very dark colours, and not be too bad on anything in between.


> For example, in Firefox, I use the dark theme for the UI, but that’s completely unrelated to the content, and prefers-color-scheme matches the content, not the chrome. Content I keep normal, light.

Of note is https://bugzilla.mozilla.org/show_bug.cgi?id=1529323 which is requesting to change this behaviour to align prefers-color-scheme to the UI theme if there is no overriding behaviour.

I prefer this because now rather than setting dark mode to each site I go to, they can be signalled this already. There's no user friendly way to set firefox's prefer-color-scheme: dark if the OS does not have the capabilities to do that.


Yeah, I’ve been waiting for that to inevitably happen so that I can revert it. Speaking overly broadly, dark mode everything is normally an at-least-slightly bad idea, but there’s good cause for aesthetic (low-contrast) dark mode of chrome in order to get it mostly out of the way, so that you can focus on the content. This is essentially what most graphics programs default to nowadays, and the same reasoning can be applied to browsers. (Though it only really works if your windows are maximised, otherwise dark between two lights could become a distraction.) No one says “you have a dark desktop background, you must want everything on your system to be dark”. Comment 47’s “When using the "Dark" theme, "prefers-color-scheme" should be dark, because that's what the user requested.” is simply not right. Choosing a dark browser theme is honestly quite a weak hint about whether you want content to be dark. The conflation of this that recent forays into OS-wide dark modes has encouraged is not good.


> There's no user friendly way to set firefox's prefer-color-scheme: dark if the OS does not have the capabilities to do that.

And even if the OS does have that capability, Firefox will ignore it for prefers-color-scheme if you have enabled enhanced tracking protection. Instead, Firefox will always claim prefers-color-scheme: light - the least they could have done is indicate no preference.


(prefers-color-scheme: no-preference) got killed off because it simply wasn’t useful in practice.


The only reason its not useful is because browsers did not implement it or removed their implementation. There is even one use in my comment: specifying not providing false information when the browser does not want to disclose any more identifying bits.


Yes GitHub does it too. The icon can't update itself so it's stuck on the color it was when you last visited the site.

Example: https://i.imgur.com/PTPJ3Fm.png


That sounds like a browser bug - if its rendering the icon in the browser chrome it should also use the color scheme setting matching the chrome.


It’s not a bug, it’s people using it to mean something it doesn’t mean.


There's a few things to be aware of with svg favicons.

1. If a favicon is missing or in a format that's not compatible with the browser. The browser will look for a /favicon.ico file at the root of the site. It's worth having that as a backup or you end up with no favicon and 404 errors in the console.

2. Google now shows a favicon in some search results. I'm pretty sure it works fine with SVG. But, if you use an emoji you end up with a missing glyph character as your favicon. it looks bad.

3. If it's inline it won't be cached

I went a bit overboard optimizing the favicon of my site, and found that:

If you design your favicon as colored squares on a 16x16 grid, and save it as a 32x32 .ico file at https://example.com/favicon.ico

You end up with a smaller file size icon, that can be cached, doesn't have any markup on your site, and scales up perfectly on all the icon sizes.

here's an example: https://doodad.dev/favicon.ico

it's just 625 bytes (261 minified)


Your favicon.ico can be compressed further to a 171 byte PNG. I confess I find this 271-byte incantation compelling despite increasing each response by that much, since it’ll load faster in the first place and avoid the overhead of another request:

  <link rel=icon href=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAG1BMVEU5PT85PT///7X22GDtiUvVOkKxOF5qMk////9bF0DJAAAAAXRSTlMAQObYZgAAAD5JREFUeNq906UBwEAUwNBy95+4cOA+09OxWSKsCE2wAQKCRhrsiMrgQFQGJ6IyuBCVwQ1YG1+wTHgQdpbTC3XuCmFsTKU6AAAAAElFTkSuQmCC>


There won't be any overhead once the file is cached. Your method requires the favicon to keep getting downloaded on every page load.


Both Chrome and Firefox (maybe others) have a separate cache for favicons that acts differently than the regular browser cache. I don't know if it caches data uris but it does cache more aggressively. I know some places like Stackoverflow add a cache-busting parameter to favicon.ico to get past it.


How would a data uri exactly get cached? It’s served inline with every page request.


I know it sounds funny, but they want a favicon cache for things like the bookmarks page and the default "blank" Chrome page, where there's no "page" present. So it's possible they extract the uri data into that cache.


It will load faster but at the expense of other things that matter more. On every page load, too. I don’t think it matters if a favicon download takes one extra round trip on the first page load. In fact I would prefer the request for the favicon to be deferred till after all my content and other assets have loaded, which I would guess browsers do by default.


using favicon.ico also has the advantage that it will show up on e.g. some rss readers


2: Why? Are there even any systems left on the planet that aren't past EOL but don't have emoji fonts preinstalled at the OS level?


Maybe because you can't guarantee that even if an OS has emoji support that it supports the latest version of emojis.

I run into this every time my wife updates her phone. She sends me text messages with "Lookit the cool new emojis!" But since I haven't updated mine, they came through as missing icon glyphs.


I think google renders them in a raster format. Whatever they use to do that doesn't support emojis.

It could be by design, by rendering any text in the svg icon google is making a design decision for you. They're choosing a font, or a specific emoji type. Maybe they want to avoid the problems that would ensue.


EOL doesn't matter - in use and in standard matters. Also the look depends on local conditions – the font. That's not what designers are keen on.


I hope SVGs as favicons gets supported by all browsers soon. Until then (shameless plug) a colleague of mine wrote a guide what is really needed in terms of favicons: https://loqbooq.app/blog/add-favicon-modern-browser-guide


Awkward ad intermission

Tired of all the "404 Not Found: /favicon.ico" log messages from your local test server? Fret no more! Just add this minor incantation to your HTML and you're set!

  <link rel="icon" href="data:," />


I prefer this:

    <link rel="icon" href="data:image/svg+xml,%3csvg%3e %3c/svg%3e">


Why is that preferable?


Because it’s a valid image.


No it’s not: the root <svg> element must exist in the http://www.w3.org/2000/svg namespace, or the file won’t be valid SVG and won’t be rendered.

Alas for my beautiful short form that won’t work after all:

  <link rel=icon href=data:image/svg+xml,<svg/%3E>
I’ll just have to settle for this:

  <link rel=icon href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'/>">
Note, however, that by making it a valid SVG file, the browser will render an empty favicon, rather than saying “this page has no favicon” and either leaving the space out or putting some default icon in instead. Consequently, `data:,` is almost certainly preferable.

(If you’re not sure why I worded the namespaces remark so rather than just talking about an xmlns attribute, here’s some valid SVG: <foo:svg xmlns:foo="http://www.w3.org/2000/svg"/>.)


Because it has all the cool benefits of SVG :p


why not just

  touch favicon.ico
so it gets cached and forget about it?


Too easy


Seems like the author is ahead of you, inlining the svg in your head tag should fix that too?


> By using an SVG, I’m able to get a lot of cool benefits like: Inline icon (no need for a linked resource)

AFAICT that's not any different than for non-SVG favicons which can also use data urls.


this is correct


I agree they are great, especially for simple icons that work as SVG. Support for SVG favicons, however, keeps me from using them: https://caniuse.com/link-icon-svg


Oh wow, Safari still doesn’t do regular SVG favicons? Huh. Somehow I thought that got sorted out a couple of years back in 12 or something.


The webdev community needs to figure out a way to give Safari the IE6 treatment, and shame Apple enough to stop holding back progress. Apple gets coddled so much everyone seems shocked when you try to tell them how awful Safari is.

Basically the only thing I really want out of all the anti-trust heading there way, is to force them to allow alternative renderers.


While Firefox has had non-broken support for SVG favicons since 2015, Chrome only added support last year. There are certainly features Safari is behind on but this isn't exactly a shining example of it.

IE6 was borderline abandonware with hideously broken implementations of many core features. Implying that Safari is comparable to IE6 is just factually wrong. No, it doesn't live on the bleeding edge like Firefox and Chrome, but it has excellent support for non-bleeding edge features. And where there are notable gaps in feature support (e.g. webp images) there are clean, formal mechanisms for fallback.

Usually when people complain about Safari, it's because they care about some bleeding edge feature (which they probably don't need anyway) or one of a few specific absent features such as web notifications. (For which I'll controversially retort with good! It's an anti-feature. Pleased that Safari is holding the line on that one.)


And where there are notable gaps in feature support (e.g. webp images) there are clean, formal mechanisms for fallback.

Facts; in addition Apple added support for WebP in Safari 14: https://webkit.org/blog/11340/new-webkit-features-in-safari-...


Webp is a format that Google pulled out of their ass and successfully pushed because of their market dominance; I don't see why Apple should help Google's hegemony.


This sounds really pandering.


When you look at it compared to actual browser usage, you end up with 89.62% support, which is not bad at all. WebP & CSS Grid are at about 95%.


Vector graphics rendered at very low resolutions like 16x16 or whatever favicons are rarely look as good as hand-crafted bitmaps. Is it possible to make them look good?


Yes, but it requires some graphics techniques that browsers mostly don’t implement, or implement in all environments, yet. I can’t remember the full range of techniques to do it properly, but it starts at least conceptually with supersampling: not rendering at 16×16, since that causes real problems with aliasing when you have overlapping objects, but rather rendering at a higher resolution (where the aliasing effects are reduced or eliminated) and scaling down. For perfect results on 8-bit colour, I think you’d need to do 16×16 supersampling (rendering 16× as large in each direction, so 256×256 and scale down to 16×16) so that each pixel is the combination of 256 pixels, but except for very fine detail, 4×4 supersampling (render at 64×64 and scale down to 16×16) should generally be good enough.

I think there are fancier ways of doing this, and of getting GPU support, but I can’t think of the terms now. Hopefully someone else will chip in.

But if you’re aware of the ways in which most renderers do an inferior job, you can work around them and craft your SVG so that it won’t be affected: things like making sure that objects align with pixel boundaries and that each pixel never has more than one object partially covering it.


I wonder if it is possible to have an ML filter that can downsample in a way that is aesthetically pleasing, even if things are not aligned at pixel-boundaries.


What you’re describing sounds like automated hinting. It’s a nice idea, but in practice it’s going to mess up too much stuff to be worth it, even if performance weren’t a problem.


I'm not so sure. Have you seen what the (loosely speaking) "inverse" operation (ML based superresolution) is capable of? E.g.:

https://www.pixelmator.com/blog/2019/12/17/all-about-the-new...


Machine learning is singularly well-suited for superresolution, because you can trivially downsample and train it on that inverse operation, so training at scale is really easy.

But pleasing hinting—even operating on raster rather than vector sources—can’t be trained in the same way, because it’s inherently more subjective; it may be possible to come up with an alternative approach to training, but I suspect it’ll still be much more prone to inducing significant errors.

And of course, performance in all these things is such that they’re not going to be shipped in browsers; from your link, that model is thousands of times more expensive than the (admittedly-inferior) alternatives. (What’s their disk space like? I’m not familiar with how big such ML models end up.)


Have to greatly simplify them. Don’t Hidef displays use 32x32 these days?


Yes, 32x32 is typically used by higher density displays (more pixels in the same space, relatively speaking).


At retina resolution it shouldn't matter.


Great news for users that weren't going to have the problem anyways, horrible news for the 16x16 rendering issues otherwise.


Was wondering if you could use this to run a version of your site in the favicon directly using `foreignObject`, but it looks like Chromium browsers at least render the SVGs in static mode [1][2]. Maybe it'll work in others though?

[1] https://www.chromestatus.com/feature/5180316371124224

[2] https://svgwg.org/svg2-draft/conform.html#secure-static-mode


Secure static mode doesn’t block foreignObject. Script execution, external references, declarative animation and interactivity, but not foreign content. Indeed, such processing modes are propagated to such foreign content: https://svgwg.org/svg2-draft/conform.html#referencing-modes.

See https://news.ycombinator.com/item?id=26922244#26923436 for an example. It works in Chromium.


>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.

Isn't it easiery to maintain if you just have to change one file instead of all sites?


What's annoying to me having created a prefers-scheme and fully-responsive favicon is getting docked by Lighthouse for not having matching dimensions for each value of these PWA dimensions. The favicon changes layout and does a nice job, but our the tool is dumb so I have to optimize for Google's tool instead of a single, maintainable file.


Related: If you're looking for a favicon generator, check out https://realfavicongenerator.net (I am not affiliated, just a satisfied user).


I find the most interesting part how < and especially “ don’t need to be escaped inside the href attribute. How does the HTML parser know when the attribute stops?


I don't think it's actually valid - the examples just aren't base64-encoding in order to make it possible to read them easily.

Edit: Yeah, you at least need to change the `"` to `'` in the inline SVG before it will parse correctly (tested in Firefox)


You need to escape special characters, but you do not need to base64-encode SVG, which gives it a slight advantage over binary formats in data URLs.


I wonder if the Gmail people could use this to give their app a non-blurry Favicon. It looks really poor when task switching between apps


re: cacheability of favicons, this is basically a non-issue as the bandwidth-delay product of even a 10mbit/50ms connection is already 62 kB. Anything below this size on such a connection is likely to render faster than a separate request round-trip.

This raises to almost 1.2 MB with a 100mbit/100ms connection.


Early on in a connection, congestion window is much more limiting than bandwidth delay product. Do you really want to spend that limited bandwidth on your favicon that you might have already sent to the user before, maybe even in the same browsing session?

It's way better to put it as a separate image, maybe their browser will delay loading it because they're mostly useless. But, you can actually make a favicon useful! If you serve http-strict-transport-security headers with includeSubdomains from your top level domain and you serve your favicon from there, you can push browsers to load them. Ex: your website at www.example.org loads https://example.org/f as its favicon with content expiration about the same as HSTS expiration, and you've now set or refreshed that.


Good argument - unless the href length approaches the size of the resource itself!

I don't understand what you're saying about the utility of the favicon with HSTS. It's not something I'm expert in, so perhaps I'm missing something? What does "push browsers to load them" mean?


If you want to tell browsers that your whole domain (*.example.com) should be https only, you need them to load something from the top level domain (example.com), they're loading is hosted on (say www.example.com or news.example.com). Any resource from https://example.com/ can serve an HSTS header with includeSubdomains, but it might as well be the favicon.


> Do you really want to spend that limited bandwidth on your favicon that you might have already sent to the user before, maybe even in the same browsing session?

That's a really going point, but if the site's coming down over classic HTTP then still possibly yes, as separate requests are liable to require additional rounds of cold start. The other detail is that I don't think I've worked with a favicon much exceeding 1500 bytes before.

Another option would be pushing the <link> into the footer, but HTML 5 seems to require <link rel="icon"> only in the header. I wonder if browsers really enforce that.


I’ve experimented with threejs and canvas for animated favicons https://codesandbox.io/s/three-js-favicon-cz1ef


No need to use SVGs for an emoji favicon. Just put the emoji and a space at the beginning of your <title>.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: