The guide
A favicon is a set, not a picture: why the smallest icon on a page takes the most care
The smallest picture a site owns is read from a container format older than most websites and shown on light and dark tab strips alike, so one picture has to become several files that each do a job.
- 0 means 256 a width or height byte of zero in an ICO directory
- 54 bytes header and directory of a three-image ICO
- 40% radius of the maskable safe circle, of the smaller side
- 3:1 the WCAG 2.2 minimum contrast for graphics
- 1.54:1 the example indigo against the dark test tab
Read the full guide Fold the guide
Most pictures on a website are made to be looked at. The favicon is made to be recognised from the corner of an eye, at a size where a single stray pixel is a tenth of the drawing. It sits in the tab, beside the address, in the bookmarks bar and the history list, and on a phone it can become a tile on the home screen. One file cannot do all of that well, so a favicon is really a small set of files, and the work lies in making each member of the set honest at its own size.
The name is short for favourite icon, and it began as a single file called favicon.ico in the root folder of a site. That habit has outlived its reason. The HTML Standard now lets a page declare any number of icons with link elements whose rel attribute is icon, and asks the browser to pick the most appropriate one by type, media and sizes, taking the last declared when several are equally good. Requesting /favicon.ico when nothing is declared is something a browser may do, not something a page should rely on.
Sixteen pixels is a different drawing
The classic favicon file holds icons of 16, 32, 48 or 64 pixels square. Drawn sixteen CSS pixels wide on a screen with two device pixels per CSS pixel, an icon needs thirty-two real pixels, which is why the standard says the sizes attribute counts raw pixels, not CSS pixels. Its own example is an icon fifty CSS pixels wide for a 2x display, which has a width of one hundred raw pixels. So the smallest useful set already holds two bitmaps for the same spot.
Shrinking a large logo to sixteen pixels is where most icons go wrong. A resampler that looks at only a few source pixels for each target pixel skips the rest once the reduction passes about one half, and fine detail is lost or turns rough. Box sampling avoids that by treating each target pixel as a box laid over the original and averaging every source pixel inside it, so all of them contribute. The cost is speed, which hardly matters for a handful of icons.
There is a trap in doing it in steps. Halving a 512 pixel master to 256 and then shrinking to 180 sounds gentle. On a pattern of single-pixel lines it landed up to 41 levels of 255 away from a true area average in our own measurement, because the halving blurred pairs of pixels before the second step split them unevenly. A step is only harmless when it is an exact two-to-one halving and the target still divides the result. From 512, the 16 pixel icon can go 512, 256, 128, 64, 32, 16; the 48 pixel icon has no such path and is made in one pass.
Even a faithful average can look soft at sixteen pixels. Unsharp masking adds back a fraction of the difference between the image and a blurred copy of it, so sharpened equals original plus the difference times an amount. Typical advice runs from half a pixel to two pixels of radius and fifty to one hundred and fifty percent of amount. At icon sizes the light end of that range is enough: a 1-2-1 blur and half the difference. More than that draws bright halos that read as a second outline.
Transparency needs its own care. If colour and alpha are averaged separately, a fully transparent pixel, whose stored colour is often black, drags its neighbours darker and leaves a grey fringe around the mark. Averaging colour already multiplied by alpha, and dividing out at the end, keeps the edge the colour it should be.
The ICO container, byte by byte
The ICO format is a small directory followed by images. A six-byte header holds a reserved zero, the number 1 for an icon, and the count of images. Each image then has a sixteen-byte entry: width and height in one byte each, a colour count, a reserved byte, planes, bits per pixel, the size of the data and where it starts. A set of three images therefore spends 54 bytes before the first pixel.
One byte can only count to 255, and the format has a rule for the largest icon: a width or height byte of 0 means 256. That rule is also a classic place to break a writer. A program that tries to store 256 in a byte gets 0 by accident if it truncates, which happens to be right, but one that stores it as a two-byte number spills a 1 into the height byte and declares a 256 by 1 picture. A reader that compares the directory with the image itself catches it at once.
Each image is stored in one of two ways. It can be a complete PNG file, copied in verbatim, whose own header gives the true size. Or it can be a device-independent bitmap: a forty-byte BITMAPINFOHEADER whose height is twice the icon’s height, the colour rows from bottom to top in blue, green, red, alpha order, and then a one-bit AND mask in which a set bit means transparent. Every row of both parts is padded to a multiple of four bytes. The 32 pixel bitmap in our worked example takes 4,264 bytes: 40 for the header, 4,096 for the colour rows and 128 for the mask. The same picture as a PNG is usually far smaller.
Convention keeps bitmaps for the small sizes and saves PNG for the 256 pixel image, because older readers could not open PNG frames. Modern ones read both, so a set of PNG frames is the compact choice, and a mixed file is the cautious one. Whatever goes inside, a good test is to read the file back with a parser that checks every entry against its data, and then to hand each entry to the browser alone and compare the pixels that come out.
PNG, SVG and the tags that point at them
Separate PNG files serve the places that ask for a specific size. Multiples of 48 pixels suit launchers, a 180 pixel touch icon is the common size for a home screen shortcut, and a web app manifest wants at least a 192 pixel and a 512 pixel icon. A PNG from a canvas may carry more than pixels. The PNG specification lets a file hold ancillary chunks for colour profiles, text and dates, and an encoder is free to add one. Keeping only IHDR, PLTE, tRNS, IDAT and IEND leaves exactly the image.
An SVG icon is the one file that stays sharp at every size, and the sizes attribute has a keyword for it: any. It can also do something no bitmap can. An SVG can carry a style element with a prefers-color-scheme media query, so a dark mark can turn light when the reader has asked for a dark interface. The rule is plain CSS inside the icon file.
The tags themselves are short. The sizes value must be a set of unique tokens, each either any or two whole numbers without a leading zero joined by a single x, and it must only claim sizes the file really holds. A generator should check its own output against that grammar every time, because a value like 016x16 or a repeated size is easy to produce and does not conform.
Dark strips and the safe circle
The same icon will be drawn on a white tab and on a charcoal one. WCAG 2.2 defines contrast from relative luminance as the lighter value plus 0.05 over the darker plus 0.05, and asks 3:1 for graphical objects. Apply it to the example mark in the tool, an indigo star, #3b3f9e, with a small gold dot. On a white tab the indigo scores 8.78:1. On the dark test tab, #2e2e34, it scores 1.54:1, and the star all but vanishes. The gold, #f2c14e, does the opposite: 8.04:1 on dark, 1.68:1 on white.
That is the case for the SVG dark rule, or for a background shape behind the mark. Either way, the check is cheap and the failure is common.
A home screen adds a mask. The W3C manifest lets an icon declare the purpose maskable, which tells the system it may cut the image to its own shape. The guarantee is a safe zone: a centred circle whose radius is 40% of the smaller side, inside which nothing may be made transparent. On a 512 pixel icon that radius is 204.8 pixels, and the largest square that fits inside it is about 289.6 pixels, or 56.6 percent of the side. Art that reaches beyond the circle may be cut off.
Testing before you ship
To reproduce the numbers above, open the tool with its example, keep the ICO at 16, 32 and 48 pixels, and switch the storage to BMP. The file list shows the three bitmaps, the checks report the directory read back and each entry decoded by the browser, and the dark tab row reports the indigo at 1.5:1, under 3:1, with the SVG dark rule lifting the icon to 8.0:1. Switch storage back to PNG and the check that compares the PNG frames with the separately saved PNG files should report every byte the same.
What a preview cannot settle is which icon a given browser or launcher will choose from your set, or which mask a particular home screen applies. Those decisions belong to the software that shows the icon. The useful promise is narrower: every file is well formed, every size is an honest average of the picture, every declared size exists, and the mark is visible on both a light and a dark strip. Check those, and the corner of the eye will do the rest.
Sources
Every source consulted for this guide. Links checked October 23, 2026.
- HTML Standard WHATWG
- HTML Standard WHATWG
- Web Application Manifest W3C
- Web Content Accessibility Guidelines (WCAG) 2.2 W3C
- Portable Network Graphics (PNG) Specification (Third Edition) W3C
- ICO (file format) Wikipedia
- Favicon Wikipedia
- BMP file format Wikipedia
- Image scaling Wikipedia
- Unsharp masking Wikipedia
- rel HTML attribute MDN Web Docs
- icons - Web app manifest MDN Web Docs
- Define your app icons MDN Web Docs
- prefers-color-scheme CSS media feature MDN Web Docs
- Add a web app manifest web.dev
- Adaptive icon support in PWAs with maskable icons web.dev