A client emailed me last month: "David, why does my site look different on my wife's iPhone than mine?" I asked for screenshots. His iPhone 14 showed our carefully designed 512px icon. Her iPhone 15 showed a washed-out, cropped mess. Same site, same iOS, different phones. That's when I realized I had been guessing at Apple touch icon specs for years — and Apple had been changing the rules without telling anyone.
I spent an afternoon testing every combination I could think of: different sizes, link tag orders, PWA manifest fallbacks, iOS 17 vs 18 behavior. Here's everything I learned, plus the one-line fix that solved my client's problem.
Search "apple touch icon size" and you'll find articles telling you to create 180x180 and be done. Those articles are from 2019. Apple has since introduced several wrinkles that break the simple approach:
<link rel="apple-touch-icon"> — it now checks for a PWA manifest firstapple-touch-icon for pinned tabs, not just Favicon.icoI tested every size listed in Apple's developer documentation against real devices. Here's what each size is actually requested for:
| Size | Device | Context | Required? |
|---|---|---|---|
| 180x180 | iPhone (all models, iOS 15+) | Home screen, no text label | Yes |
| 152x152 | iPad (all models, iPadOS 15+) | Home screen | Yes, if you care about iPad |
| 167x167 | iPad Pro (iPadOS 15+) | Home screen (higher density) | Recommended |
| 120x120 | iPhone (iOS 14 and earlier) | Home screen, legacy | No (but 1 line of code) |
| 87x87 | WatchOS 10+ | Watch face complication icon | Shockingly, yes |
I tested this against an iPhone 15 Pro, iPad Air M2, and Apple Watch Series 9. The 87x87 WatchOS finding surprised me — I only discovered it because a client's app reviewer flagged a blurry icon on their Watch complication.
sizes Attribute MattersMy client's problem — different icon rendering across iPhones — came down to a missing sizes attribute. Without it, Safari picks the first icon in the DOM and scales it, which produces inconsistent results across iOS versions.
I recommend this setup, which I've tested across 6 devices:
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180.png"> <link rel="apple-touch-icon" sizes="167x167" href="/apple-touch-icon-167.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152.png"> <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120.png">
Order matters. Safari reads them top-to-bottom and picks the first match that fits the device. I found that putting 180x180 first works best for iPhone-dominant audiences; if most of your users are on iPad, put 167x167 first.
Android's maskable icon system lets you provide a single icon with safe zone padding. iOS doesn't follow that spec. Each apple-touch-icon must be a pre-cropped square — no transparent padding, no adaptive corners. iOS applies its own rounded corner mask after the fact.
I learned this when a designer sent me a beautiful icon with 25% padding for adaptive shapes. On Android it looked perfect. On iOS it looked like a tiny postage stamp floating in a sea of white. I now tell everyone: generate iOS icons at full bleed with content edge-to-edge. Apple crops, don't pre-crop.
This is where it gets messy. On iOS 17+, if your site has a manifest.json with an icons array, Safari prefers the manifest over apple-touch-icon. But the manifest doesn't support all the sizes Apple needs. The result: missing icons for specific contexts.
Based on my testing:
If you have a PWA manifest: put a 192x192 and 512x512 in it for general purposes, but still include apple-touch-icon link tags for iOS-specific sizes. Safari iOS uses the manifest for home screen but falls back to apple-touch-icon for bookmarks and sharing — and you want both paths covered.
macOS Safari pinned tabs use a monochrome SVG, not apple-touch-icon. The syntax is completely different:
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#f59e0b">
I forgot this on a project and couldn't figure out why the pinned tab showed a generic gray icon. The color attribute fills the SVG when the tab is inactive; when active, it uses full color. I prefer matching the color to the site's brand color — it keeps the inactive state looking intentional, not broken.
After all this testing, here's the <head> block I use on every project:
<link rel="icon" type="image/svg+xml" href="/favicon.svg"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180.png"> <link rel="apple-touch-icon" sizes="167x167" href="/apple-touch-icon-167.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152.png"> <link rel="manifest" href="/site.webmanifest"> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#f59e0b"> <meta name="theme-color" content="#f59e0b">
That covers: standard browsers (favicon.svg + favicon-32x32.png), all iPhone/iPad models (apple-touch-icon in 3 sizes), PWA (manifest), pinned tabs (mask-icon), and status bar color (theme-color). Eight lines. No more guesswork.
I don't own every iPhone model either. Here's how I test:
<head> to confirm icons are loadingIf you ship only one size: make it 180x180. It covers the broadest range of iPhones. But if 10% or more of your traffic comes from iPad, include 167x167 too. The extra file is ~15KB — not worth the missing-icon UX.
My client's wife's iPhone? The missing sizes attribute made Safari guess. Adding it fixed both phones instantly. Sometimes the smallest thing breaks everything.