The iOS pipeline does not read rel="icon" at all for home screen installation. It reads rel="apple-touch-icon" and, for installed PWAs, the web app manifest. That split is the reason a site can look correct in Safari tabs and still install with a fuzzy or missing icon.
apple-touch-icon: 180 × 180
The current recommended size is 180 × 180. Older devices use 120 × 120, but a single 180 × 180 file is scaled down cleanly and is the only one you need to maintain. The file should be opaque: iOS does not render transparency, and alpha pixels are composited against black, which is how white logos become black squares.
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<!-- iOS applies its own rounded-corner mask. Do not pre-round the artwork. -->
<!-- Apple also ignores any declared background colour for this icon. --> Why transparency becomes black
A PNG with an alpha channel placed on a home screen is flattened against black, not white. A dark wordmark on transparency becomes invisible; a white wordmark on transparency looks correct by accident. Flatten onto your brand background before export and the result is predictable on every device.
The manifest set: 192 and 512
For an installable PWA, Android reads the manifest rather than the HTML. Two sizes are required: 192 × 192 for the home screen and 512 × 512 for the splash screen and install prompt. Anything else is optional, and adding ten redundant sizes only slows the install.
{
"icons": [
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "/icons/maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]
} Maskable icons and the 80% safe zone
Android crops maskable icons to whatever shape the launcher uses — circle, squircle or rounded square. Only a centred circle with a diameter equal to 80% of the icon is guaranteed to stay visible. Put the logo inside that circle and let the background fill the rest.
Do not mark a regular icon as maskable to save an export. The launcher will crop a full-bleed design and cut the logo in half, which is worse than shipping no maskable icon at all.
Splash screens
Android generates splash screens from the 512 icon plus the manifest background and theme colours. A mismatched background_color produces a visible flash between the splash and the first paint. Set both values explicitly instead of relying on defaults.
Testing on a real device
- 01 Open the site in iOS Safari and use Share → Add to Home Screen.
- 02 Confirm the icon is opaque and not cropped by the rounded mask.
- 03 On Android Chrome, check Install app in the menu and inspect both normal and maskable rendering.
- 04 Clear the site data before retesting — home screen icons cache aggressively.