How to fix Chrome's PWA icons in macOS 27
Since late 2026, a web app installed with Chrome on macOS 26 or 27 can show a frame, a colored border, padding, or a thin edge line around its dock icon. The same app added to the Dock from Safari looks fine. The fix is in the icon artwork, not the browser.
How it used to work
- Chrome on macOS builds the installed app's dock icon from the manifest's maskable icon when there is one. It falls back to the any icon only when there's no maskable icon.
- Chrome masked that icon itself to match Apple's older icon template. It kept only the center 80% of the image (about 10% trimmed from every side) and clipped it to a rounded square with a soft shadow.
- Because of that crop, the outer ~10% of a maskable icon was never visible on a Mac. A border, a different-colored margin, or padding in that outer band went unnoticed. It showed only in Android's circle crop, where few people looked closely.
What changed
- A Chromium change landed on August 18, 2026: Stop masking web app icons on macOS 26.
- On macOS 26 and later (including macOS 27), Chrome no longer crops the maskable icon. It hands the whole image to macOS, which applies its own icon treatment: it rounds the corners of the full square and doesn't trim the edges.
- Anything in the outer band of the maskable icon is now visible in the Dock, Launchpad and app switcher: frames, borders, padding in another color, and edge lines from images whose background doesn't quite reach the edge. A glyph that was sized for the old crop also looks smaller.
- Chrome on macOS 15 and older still uses the old crop.
- Safari's "Add to Dock" uses the any icon and wasn't affected.
How to fix it
- Keep the maskable icons. Chrome on macOS, Android, ChromeOS and Windows all use them. Without one, Chrome on older macOS shows the any icon as a plain square, and Android puts it inside a white circle.
- Make the maskable art truly full-bleed. The icon's own background color or gradient must run all the way to every edge: no frame, no border, no padding in a different color, no transparent margin.
- Keep the logo inside the safe zone. That's a centered circle with a diameter of 80% of the icon (a radius of 40%). Anything outside it can be cut off by circular masks. For macOS 26+, a logo about 50–55% of the icon's width looks like a native Mac app icon.
- Render every size from a vector source (SVG). Make sure the background shape covers the whole canvas. A background rectangle that's a fraction of a pixel short leaves a thin light line along the right and bottom edges.
- Use new file names (or a version in the path) so no cache keeps serving the old images.
- Reinstall the app. Chrome on desktop doesn't update an installed app's icon by itself. Uninstall it from the app's ⋮ menu, leaving "clear data" unchecked, then install it again.
To check an icon, open it on maskable.app and switch between the mask shapes. The background should fill every shape, including the full square.
Example manifest
json
{
"name": "Example App",
"short_name": "Example",
"start_url": "/",
"scope": "/",
"display": "standalone",
"theme_color": "#007392",
"background_color": "#007392",
"icons": [
{ "src": "/icons/app-1024.png", "sizes": "1024x1024", "type": "image/png", "purpose": "any" },
{ "src": "/icons/app-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" },
{ "src": "/icons/maskable-1024.png", "sizes": "1024x1024", "type": "image/png", "purpose": "maskable" },
{ "src": "/icons/maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" },
{ "src": "/icons/maskable-192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable" },
{ "src": "/icons/maskable-96.png", "sizes": "96x96", "type": "image/png", "purpose": "maskable" },
{ "src": "/icons/maskable-48.png", "sizes": "48x48", "type": "image/png", "purpose": "maskable" }
]
}Rules for the manifest:
- List the any icons first, then the maskable ones.
- Never combine them as "purpose": "any maskable" on one entry. Give each purpose its own entries.
- The any icon should also be a full-bleed, opaque square. Safari applies its own mask and margin to it.
- Serve the manifest as application/manifest+json.