- From: carlosjeurissen <notifications@github.com>
- Date: Sun, 01 Feb 2026 01:34:08 -0800
- To: w3c/manifest <manifest@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3c/manifest/issues/975/3830708925@github.com>
carlosjeurissen left a comment (w3c/manifest#975)
As @Sascha-Block mentioned `color_scheme_dark` for color declarations like `theme_color` seems to be the right approach for the many reasons listing. For icons specifically, using `color_scheme_dark.icons_localized`, after writing down a real world example like Yandex, there might be some concerns we want to address (See below).
@christianliebel thanks for the update! The backwards compatibility sure is something we need to resolve. After some testing: even within the same implementation (chromium), given two equal options, sometimes the first declaration is used and sometimes the last declaration (@dmurph in my test the "install app" submenu item uses a different order from the actual installation prompt).
However, if we use the exact syntax as used in webExtension icon_variants, as specified in [doc](https://github.com/w3c/webextensions/blob/main/proposals/dark_mode_extension_icons.md). Each new syntax declaration will not have the src property and will thus safely be ignored by most implementations. This would allow to have both syntaxes in the same `icons` list as mentioned during TPAC @diekus. Basically by omitting the src property, you do something similar as was done in css with `@media only screen`. It basically poisons the declaration so it is only used in modern implementations.
As such:
```json
"icons": [{
"512": "icon-512.png",
"192": "icon-192.png"
}, {
"src": "icon-512.png",
"sizes": "512x512"
}]
```
### Real world example.
Given a company like Yandex. It uses a Cyrillic icon for the Cyrillic writing world (Belarusian, Russian, Ukrainian) and a Latin icon for the rest of the world.
Given a simple example in which the Yandex app would offer a light theme icon, dark theme icon, and monochrome icon in 32, 192 and 512px sizes.
### Single `icons` waterfall list (webExtension icon_variants)
```js
{
"lang": "en",
"icons": [
// Localized Monochrome (Cyrillic)
{
"512": "cyrillic-monochrome-512.png",
"192": "cyrillic-monochrome-192.png",
"32": "cyrillic-monochrome-32.png",
"lang": ["ru", "uk", "be"],
"purpose": ["monochrome"]
},
// Default Monochrome (Latin)
{
"512": "latin-monochrome-512.png",
"192": "latin-monochrome-192.png",
"32": "latin-monochrome-32.png",
"purpose": ["monochrome"]
},
// Localized Dark (Cyrillic)
{
"512": "cyrillic-dark-512.png",
"192": "cyrillic-dark-192.png",
"32": "cyrillic-dark-32.png",
"lang": ["ru", "uk", "be"],
"color_schemes": ["dark"]
},
// Localized Light (Cyrillic)
{
"512": "cyrillic-light-512.png",
"192": "cyrillic-light-192.png",
"32": "cyrillic-light-32.png",
"lang": ["ru", "uk", "be"]
},
// Default dark (Latin)
{
"512": "latin-dark-512.png",
"192": "latin-dark-192.png",
"32": "latin-dark-32.png",
"color_schemes": ["dark"]
},
// Default light (Latin)
{
"512": "latin-light-512.png",
"192": "latin-light-192.png",
"32": "latin-light-32.png"
},
// Legacy
{
"src": "latin-monochrome-512.png",
"sizes": "512x512",
"purpose": "monochrome"
},
{
"src": "latin-light-512.png",
"sizes": "512x512"
}
]
}
```
### `color_scheme_dark.icons_localized`
@marcoscaceres if we do not specify the specific fallback behaviour and let this up to the implementation. Authors would have to repeat every icon variation across each icons declaration. Even with just three icon sizes (many developers declare 6+ sizes), and three variations (light, dark, monospace), we already get this monster:
```json
{
"lang": "en",
"icons": [
{
"src": "latin-light-512.png",
"sizes": "512x512"
},
{
"src": "latin-light-192.png",
"sizes": "192x192"
},
{
"src": "latin-light-32.png",
"sizes": "32x32"
},
{
"src": "latin-monochrome-512.png",
"sizes": "512x512",
"purpose": "monochrome"
},
{
"src": "latin-monochrome-192.png",
"sizes": "192x192",
"purpose": "monochrome"
},
{
"src": "latin-monochrome-32.png",
"sizes": "32x32",
"purpose": "monochrome"
}
],
"icons_localized": {
"ru": [
{
"src": "cyrillic-light-512.png",
"sizes": "512x512"
},
{
"src": "cyrillic-light-192.png",
"sizes": "192x192"
},
{
"src": "cyrillic-light-32.png",
"sizes": "32x32"
},
{
"src": "cyrillic-monochrome-512.png",
"sizes": "512x512",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-192.png",
"sizes": "192x192",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-32.png",
"sizes": "32x32",
"purpose": "monochrome"
}
],
"uk": [
{
"src": "cyrillic-light-512.png",
"sizes": "512x512"
},
{
"src": "cyrillic-light-192.png",
"sizes": "192x192"
},
{
"src": "cyrillic-light-32.png",
"sizes": "32x32"
},
{
"src": "cyrillic-monochrome-512.png",
"sizes": "512x512",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-192.png",
"sizes": "192x192",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-32.png",
"sizes": "32x32",
"purpose": "monochrome"
}
],
"be": [
{
"src": "cyrillic-light-512.png",
"sizes": "512x512"
},
{
"src": "cyrillic-light-192.png",
"sizes": "192x192"
},
{
"src": "cyrillic-light-32.png",
"sizes": "32x32"
},
{
"src": "cyrillic-monochrome-512.png",
"sizes": "512x512",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-192.png",
"sizes": "192x192",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-32.png",
"sizes": "32x32",
"purpose": "monochrome"
}
]
},
"color_scheme_dark": {
"icons": [
{
"src": "latin-dark-512.png",
"sizes": "512x512"
},
{
"src": "latin-dark-192.png",
"sizes": "192x192"
},
{
"src": "latin-dark-32.png",
"sizes": "32x32"
},
{
"src": "latin-monochrome-512.png",
"sizes": "512x512",
"purpose": "monochrome"
},
{
"src": "latin-monochrome-192.png",
"sizes": "192x192",
"purpose": "monochrome"
},
{
"src": "latin-monochrome-32.png",
"sizes": "32x32",
"purpose": "monochrome"
}
],
"icons_localized": {
"ru": [
{
"src": "cyrillic-dark-512.png",
"sizes": "512x512"
},
{
"src": "cyrillic-dark-192.png",
"sizes": "192x192"
},
{
"src": "cyrillic-dark-32.png",
"sizes": "32x32"
},
{
"src": "cyrillic-monochrome-512.png",
"sizes": "512x512",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-192.png",
"sizes": "192x192",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-32.png",
"sizes": "32x32",
"purpose": "monochrome"
}
],
"uk": [
{
"src": "cyrillic-dark-512.png",
"sizes": "512x512"
},
{
"src": "cyrillic-dark-192.png",
"sizes": "192x192"
},
{
"src": "cyrillic-dark-32.png",
"sizes": "32x32"
},
{
"src": "cyrillic-monochrome-512.png",
"sizes": "512x512",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-192.png",
"sizes": "192x192",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-32.png",
"sizes": "32x32",
"purpose": "monochrome"
}
],
"be": [
{
"src": "cyrillic-dark-512.png",
"sizes": "512x512"
},
{
"src": "cyrillic-dark-192.png",
"sizes": "192x192"
},
{
"src": "cyrillic-dark-32.png",
"sizes": "32x32"
},
{
"src": "cyrillic-monochrome-512.png",
"sizes": "512x512",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-192.png",
"sizes": "192x192",
"purpose": "monochrome"
},
{
"src": "cyrillic-monochrome-32.png",
"sizes": "32x32",
"purpose": "monochrome"
}
]
}
}
}
```
### Pros/cons
The waterfall would align the syntax with webExtensions. It allows the author to declare which selection criteria are more important (It can choose to put the monochrome icon above any language filters if the monochrome icon is universal for all languages). This syntax is the most compact and dry, yet gives authors more responsibility in correct declarations.
The waterfall would result in implementations having to maintain two types of syntaxes. Which adds implementation complexity. However the waterfall approach is very flexible. If specific other filters were to be added, it allows graceful fallbacks to items later in the list.
The `color_scheme_dark.icons_localized` would result in authors having to copy all icon declarations across all buckets. Which can be a nightmare to maintain. Let alone if we ever introduce another color_scheme or another kind of layer. To tackle this, we may be able to come up with a logical fallback system and specify it in https://github.com/w3c/manifest/pull/1205 @christianliebel. However this does not seem straightforward. If we were to come up with a fallback system, this logic is the locked and responsibility of the spec and the implementations. If we go for the waterfall approach, we move this responsibility to the manifest authors. Which actually reduces spec and implementation complexity.
While we indeed risk further delaying progress, as others have mentioned we are getting close to the point of no return and we want to make sure we are making the right decision here.
--
Reply to this email directly or view it on GitHub:
https://github.com/w3c/manifest/issues/975#issuecomment-3830708925
You are receiving this because you are subscribed to this thread.
Message ID: <w3c/manifest/issues/975/3830708925@github.com>
Received on Sunday, 1 February 2026 09:34:12 UTC