w3c / manifest

Manifest for web apps
https://www.w3.org/TR/appmanifest/
Other
653 stars 159 forks source link

Add support for defining a theme color for both light & dark modes (prefers color scheme) #975

Open jensimmons opened 3 years ago

jensimmons commented 3 years ago

Currently, in a web manifest file, you can define a theme color. https://www.w3.org/TR/appmanifest/#theme_color-member For example:

{
    "lang": "en",
    "short_name": "Resilience",
    "name": "Resilient Web Design by Jeremy Keith",
    "description": "A web book in seven chapters on the past, present, and future of web design. By Jeremy Keith.",
    "background_color": "#5f7995",
    "theme_color": "#5f7995"
}

There's not currently any way to express that a certain theme color should be used for light mode, while another is used for dark mode.

In HTML, there's currently a proposal to add support for color schemes by adding a media attribute to the meta tag: https://github.com/whatwg/html/issues/6495

<meta name="theme-color" media="(prefers-color-scheme: light)" content="red">
<meta name="theme-color" media="(prefers-color-scheme: dark)"  content="darkred">

It would be great to be able to do a similar thing in the web manifest file.

tomayac commented 3 years ago

Good catch @tomayac (and @aarongustafson, just noticed you spotted it too šŸ¦…šŸ‘€)! Updated above...

All credits to Aaron.

mgiuca commented 3 years ago

Cool, I'm happy with Marcos proposal. Thanks for taking all this feedback on board!

Should we call it media_preferences instead of user_preferences if it's going to be restricted to preferences relating to colours and such? user_preferences seems quite generic, like for example it could incorporate languages and anything else the user wants to change.

(On the other hand, maybe we could put language selection in here too... but that's probably overcomplicating the design.)

tomayac commented 3 years ago

Calling it user_preferences leaves the door open for doing more than we currently do, and at the same time isn't wrong if we do just media-related things at the moment or ever.

aarongustafson commented 3 years ago

Cool, I'm happy with Marcos proposal. Thanks for taking all this feedback on board!

Agreed. The consistent use of underscores makes it a lot easier to read too.

Should we call it media_preferences instead of user_preferences if it's going to be restricted to preferences relating to colours and such? user_preferences seems quite generic, like for example it could incorporate languages and anything else the user wants to change.

I'm still not fully sold on user_preferences as the key. I keep drifting back to media_overrides as being more explicit because it establishes a more obvious connection to media queries via the "media" portion and makes it clear that this is for changing existing values via "overrides" (and also draws the connection to display_overrides).

Is it a hill I'm willing to die on? No. Would I prefer an obvious key name? Yes.

(On the other hand, maybe we could put language selection in here too... but that's probably overcomplicating the design.)

Please no šŸ˜…

marcoscaceres commented 3 years ago

Ok, I think we have enough to go on... we can chew a bit more on user_preferences VS media_overrides VS display_overrides once we have the rest in place.

@aarongustafson, you expressed an interest in spec'ing it above. You want to take it? I can review and prototype along.

Please no šŸ˜…

Agree... let's not... BUT, it does give us a nice model/structure to follow.

mgiuca commented 3 years ago

We're into bikeshed town! Let's go.

makes it clear that this is for changing existing values via "overrides" (and also draws the connection to display_overrides).

The "overrides" has slightly different meaning in those two contexts:

I think the word "override" makes sense to both of these, but they aren't analogous to each other, so I would try to avoid overloading that term.

aarongustafson commented 3 years ago

@aarongustafson, you expressed an interest in spec'ing it above. You want to take it? I can review and prototype along.

Yep. I should have some time in the next 1-2 weeks to get a PR draft together.

dmurph commented 3 years ago

Now that we're bikeshedding - regarding the meta attribute (https://bugs.chromium.org/p/chromium/issues/detail?id=1200528&):

 <!-- In dark mode, the theme color is black, otherwise it's white. -->
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#ffffff">
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#000000">

"override" could also be a great name if it would override this as well (if there were entries in both). But it might also be confusing if that isn't what the ending behavior is.

Is it worth it to bikeshed the question of "how would this feature interact with meta media attribute"?

jensimmons commented 3 years ago

"override" could also be a great name if it would override this as well (if there were entries in both). But it might also be confusing if that isn't what the ending behavior is.

Is it worth it to bikeshed the question of "how would this feature interact with meta media attribute"?

This is a good point ā€”Ā that "override" might not be the right word, because this does not override what's defined in a page's HTML head. If the Author defines values in both the manifest file & the HTML head ā€” HTML wins. Manifest does not override. HTML has priority.

I don't believe we can bikeshed the interaction between Manifest files and HTML meta tags. It's already specified, and implemented according to spec. A change to this behavior would likely create compat problems.

marcoscaceres commented 3 years ago

HTML wins. Manifest does not override. HTML has priority.

Agree. We might need to make that more explicit in the HTML spec (or at least add a note over there).

We should test for this too, just to confirm the above holds.

aarongustafson commented 3 years ago

If the Author defines values in both the manifest file & the HTML head ā€” HTML wins. Manifest does not override. HTML has priority.

Completely agree as it follows the path of both embedded (and inline) CSS and meta[http-equiv].

aarongustafson commented 3 years ago

@marcoscaceres @mgiuca @tomayac Iā€™ve begun working on the PR and had a few thoughts/questions about the best way to define the individual override items. Consider these in context of the syntax we are proposing (above):

First, the key for the condition being evaluated could be prefers_color_scheme or forced_colors or contrast and so on. That feels unnecessarily verbose to spec. Additionally it would require us to sync any changes to MQ user preferences with our own spec, all of which feels more fragile overall. Standardizing the key as "media" and allowing the value to be any user-preference MQ defined in the MQ spec seems much more straightforward despite the potential pitfalls of having to rely on the CSS engine as Matt pointed out.

The proposed approach also suffers from being counter-intuitive because the hyphens from CSS are replaced with underscores to match the manifest spec (and JS in general). Our crawler has already found some instances where manifest members are accidentally hyphenated instead of underscored and I can only imagine this will add to the confusion.

Second, as color overrides (or whatever we ultimately call them), weā€™re only looking at two override values, which would be pretty easy to spec out. If, however, we wanted to consider this in the context of some of the other overrides weā€™ve discussed (e.g., translations #676 as Marcos mentioned), we might consider a generic Override Item thatā€™s something like this:

{
  "condition": "(prefers-color-sheme: dark)",
  "overrides": {
    "theme_color": "#000000",
    "background_color": "#000000"
  }
}

Iā€™m not saying this is the right way to go, but it would allow us to maintain a generic that we could work it into the two use cases we have now. Or we could consider subclassing it for each context, redefining the condition key as media in the case of this proposal or language/lang in the case of translations. In either case, the context would allow us to define the acceptable keys within that instance.

Even if we didnā€™t go the subclassing route and create distinct Color/Media Override and Translation items, using the same structure in both places might be useful.

BTW - Iā€™m not married to the property names, just throwing out a potential approach that could streamline the spec process.

Alternately, if yā€™all know of specs with similar use cases that require an object to comprise a dynamic set of keys with none of them required, please point me to that so I can wrap my head around that specā€™s approach.

tomayac commented 3 years ago

I'm trying to optimize this from a web developer's standpoint. Here are my criteria:

aarongustafson commented 3 years ago

Thanks for that @tomayac, I think we're mostly in agreement. I was thinking a bit more about this this morning and had an idea about the generic being an "adaptation block" with a "context" and a "redefine" object (names to be bikeshedded). This generic could be used in the context of user_preferences (or user_preference_overrides) wherein the context needs to be a valid (and simple) user preference media query. In translations the context would need to be a valid language code. In either case, the redefine or overrides block would be an object with a specific set of acceptable keys as determined by where it's used.

dmurph commented 3 years ago

Just brainstorming some ideas instead of override, as this might be confusing w.r.t. the HTML version:

for the list name:

for the item field:

aarongustafson commented 3 years ago

@dmurph Agreed we need something to be clear. I was writing the above on my mobile, so to clarify, what Iā€™m thinking would end up looking something like this:

{
  "name": "My super cool app",
  "theme_color": "#ff9900",
  "background_color": "#ebebeb",
  "user_preferences": [
    {
      "context": "(prefers-color-scheme: dark)",
      "redefine": {
        "theme_color": "#bdbdbd",
        "background_color": "#000000"
      }
    },
  ],
  "translations": [
    {
      "context": "de",
      "redefine": {
        "name": "Meine super coole App"
      }
    }
  ]
}

I think the "context" (or a similar term) and the block that is being redefined (or that contains overrides) makes a pretty strong mental connection between the two. Again, not necessarily married to the terms, but I think keeping it more broadly applicable will enable us to re-use this pattern in numerous places. Then in each use, we can define what strings are acceptable for the context value and which members can be redefined in the block. For the block name, I think keeping the nomenclature clear about the fact that it is replacing/supplanting/redefining/overriding existing manifest values is key. Options Iā€™d thought about include:

Of the ones you suggested, I think "values" could also work, though it is key/value pairs, so itā€™s not entirely accurate.

For the context of this feature, I think Iā€™m coming back around to user_preferences, especially if we are not looking to support the entirety of Media Query features and are limiting it to user preference MQs specifically (which would be my preference).

tomayac commented 3 years ago

I could live with this, @aarongustafson.

Just for clarity, are you pursuing your ImageResource proposal in parallel?

It would work well with "icons" to exclusively focus on the proposal in this Issue (and not pursue the ImageResource proposal):

{
    "name": "My super cool app",
    "theme_color": "#ff9900",
    "background_color": "#ebebeb",
    "icons": [{
        "src": "light.png",
        "type": "image/png",
        "sizes": "512x512"
    }],
    "user_preferences": [{
        "context": "(prefers-color-scheme: dark)",
        "redefine": {
            "theme_color": "#bdbdbd",
            "background_color": "#000000",
            "icons": [{
                "src": "light.png",
                "type": "image/png",
                "sizes": "512x512"
            }]
        }
    }],
    "translations": [{
        "context": "de",
        "redefine": {
            "name": "Meine super coole App"
        }
    }]
}

But we again have a problem with the "shortcuts" member. The only way to avoid duplication would be to rely on array order in "shortcuts". The example below shows how this could look like with just one shortcut, but it gets messier when there are more shortcuts:

{
    "name": "My super cool app",
    "theme_color": "#ff9900",
    "background_color": "#ebebeb",
    "shortcuts": [{
        "name": "Play",
        "short_name": "Play",
        "description": "Play the list of podcasts",
        "url": "/play?utm_source=homescreen",
        "icons": [{
            "src": "/icons/play-light.png",
            "sizes": "192x192"
        }]
    }],
    "icons": [{
        "src": "light.png",
        "type": "image/png",
        "sizes": "512x512"
    }],
    "user_preferences": [{
        "context": "(prefers-color-scheme: dark)",
        "redefine": {
            "theme_color": "#bdbdbd",
            "background_color": "#000000",
            "icons": [{
                "src": "light.png",
                "type": "image/png",
                "sizes": "512x512"
            }],
            "shortcuts": [{
                "icons": [{
                    "src": "/icons/play-dark.png",
                    "sizes": "192x192"
                }]
            }]
        }
    }],
    "translations": [{
        "context": "de",
        "redefine": {
            "name": "Meine super coole App",
            "shortcuts": [{
                "name": "Abspielen",
                "short_name": "Abspielen",
                "description": "Spiel die Podcast-Liste",
                "url": "/play?utm_source=homescreen&lang=de"
            }]
        }
    }]
}
aarongustafson commented 3 years ago

Just for clarity, are you pursuing your ImageResource proposal in parallel?

100% yes. I totally forsee what youā€™ve outlined happening and it makes me itchy. I would like to see icons be able to adapt on their own and for that feature to land alongside this one to avoid the situation youā€™ve outlined. Ideally, icons would only need to be swapped out if their is some language-specific component to them.


I know this is only tangentially-related to the this issue, but I wonder what yā€™all might think about adding a unique id to complex structures in the manifest (e.g., shortcuts) in order to allow them to be referenced for redefinition of specific properties within as opposed ot the whole structure. So in the case of @tomayacā€™s second example, above, we could swap individual keys like this:

{
    "name": "My super cool app",
    "theme_color": "#ff9900",
    "background_color": "#ebebeb",
    "shortcuts": [{
                "id": "shortcut-1",
        "name": "Play",
        "short_name": "Play",
        "description": "Play the list of podcasts",
        "url": "/play?utm_source=homescreen",
        "icons": [{
            "src": "/icons/play-light.png",
            "sizes": "192x192"
        }]
    }],
    "icons": [{
        "src": "light.png",
        "type": "image/png",
        "sizes": "512x512"
    }],
    "user_preferences": [{
        "context": "(prefers-color-scheme: dark)",
        "redefine": {
            "theme_color": "#bdbdbd",
            "background_color": "#000000"
        }
    }],
    "translations": [{
        "context": "de",
        "redefine": {
            "name": "Meine super coole App",
            "shortcuts": [{
                "id": "shortcut-1",
                "short_name": "Abspielen",
                "description": "Spiel die Podcast-Liste"
            }]
        }
    }]
}
tomayac commented 3 years ago

Just for clarity, are you pursuing your ImageResource proposal in parallel?

100% yes. I totally forsee what youā€™ve outlined happening and it makes me itchy. I would like to see icons be able to adapt on their own and for that feature to land alongside this one to avoid the situation youā€™ve outlined. Ideally, icons would only need to be swapped out if their is some language-specific component to them.

In this case, we should try to see if we can align both proposals as much as possible.

I know this is only tangentially-related to the this issue, but I wonder what yā€™all might think about adding a unique id to complex structures in the manifest (e.g., shortcuts) in order to allow them to be referenced for redefinition of specific properties within as opposed ot the whole structure.

This sounds like a primary use case for JSON Path.

aarongustafson commented 3 years ago

@marcoscaceres @mgiuca Any thoughts here on creating a unified structure for complex overrides like these?

mgiuca commented 2 years ago

(late to the party)

I do like this unified design to both the translations and theme colour work. It's great to have people thinking across use cases like this. šŸ‘

I do have some thoughts on the specifics:

  1. We do seem to be back to using CSS media queries ("(prefers-color-scheme: dark)"). I thought we discussed this above and came to a conclusion that that was overkill. I am quite concerned about this. I don't think it's implementable, and if we can implement it, it drastically complicates the manifest parser (to include a large chunk of the CSS parser). I might be proven wrong here, but I would want to see a detailed sketch of how a user agent like Chromium might go about implementing the MQ parser (as well as how we would process it in all the OSes that we support), before we go down this route.
  2. Contrary to what I said above, I think "overrides" is the best name that you've suggested. You mentioned "redefine" and "replace" because they're "active"; I think it's not good to name things as active names inside a declarative format. We should think of this in the passive sense as "these are the overrides", not active "replace the above with these".
  3. I don't like reusing the key "context" for both user preferences and translations. In the former, it's a media query; in the latter it's a language name. The name of the key should reflect the thing you want to put in it, so for example in translations, it should be called "language".
aarongustafson commented 2 years ago

@mgiuca Thanks!

  1. Agreed. Not my area of expertise (nor a strongly held opinion from my side). I can do some digging as to how adaptive icons show up in Windows and Mac. I imagine Chrome OS would be substantially easier, but I could be wrong.
  2. Iā€™m cool with "overrides" (acknowledging the probable spelling issue).
  3. I donā€™t disagree, but I am curious how you might define a generic though. Would it be an object with a single "overrides" member and a not about it requiring the addition of a "context"? Or could we have the "context" member in the generic and then allow it to be renamed for the individual implementations (to "media" and "language"/"lang")? I donā€™t know enough about Infra to know which approach is recommended here.

Once we come to a resolution on 3, Iā€™m happy to write up an explainer for the generic (and help adapt the translations explainer) to align while we sort out the media portion (which also influences ImageResource).

mgiuca commented 2 years ago

@aarongustafson

  1. I think it's important to figure out whether we're doing the light/dark thing just for an active browser window (e.g. the title bar colour), or if we're intending to apply it wherever a manifest is used (e.g. in OS shelf icons). If it's the former, then I think it's tractable (but still architecturally difficult) to use a CSS MQ since that code resides within the browser. If the latter, it means we need to find a way to translate the MQ condition out into every OS. While Chrome OS is probably easier since we control it, it isn't limitless -- we don't really want to put a CSS engine into the OS app service just to calculate theme colours.
  2. Note that "override" is already a word (e.g. display_override); I don't think the spelling is a problem (this isn't one of those words that can be spelled two ways, "overide" is simply a misspelling, like "referer" lol).
  3. I think we need to workshop the layout of the combined translations / color scheme further, but if anything, if we want to generalize it, I would look at generalizing the top-level object. You have translations / context and user-preferences / context, and I was suggesting to rename "context" to perhaps language and color-scheme so it's clear what "type" it has. If you want to generalize it, you might consider generalizing the top-level one to just alternatives (for example), with language and color-scheme as selectors inside it. This would potentially open up a can of worms allowing for alternatives with both a language and color-scheme selector -- I'm not sure it's worth allowing for combinatorial conditions like this, so my preference would be to keep the designs consistent, but separate: translations / language and user-preferences / color-scheme.
loubrett commented 2 years ago

I like the idea of aligning this and translations. The current proposal for translations is an object with the languages as keys and an object containing the translated members as the values:

"translations": {
    "fr": {
      "name": "Bon chien",
      "description": "Une application pour chiens",
      "icons": [],
      "screenshots": []
    }
  },

The main difference between translations and user preferences is that order matters for user preferences but not translations. So the translations proposal wouldnā€™t suit user preferences unless we rely on the JSON object being ordered (which probably isnā€™t a good idea as discussed earlier in the thread). I think this context/redefine proposal works well for both.

This design also allows more fields to be added later alongside context and redefine. Iā€™m not sure what (if anything) would be added but I think itā€™s good to have the option.

We could also allow the context string to have multiple comma separated values to reduce duplication. (eg ā€œcontextā€: ā€œen-AU, en-NZā€).

I think we shouldnā€™t allow overlap between the members that can be redefined in translations and user preferences, otherwise we need to figure out what happens if something is defined in both.

tomayac commented 2 years ago

The main difference between translations and user preferences is that order matters for user preferences but not translations. So the translations proposal wouldnā€™t suit user preferences unless we rely on the JSON object being ordered (which probably isnā€™t a good idea as discussed earlier in the thread). I think this context/redefine proposal works well for both.

The ordering actually matters for "shortcuts".

aarongustafson commented 2 years ago
  1. I think it's important to figure out whether we're doing the light/dark thing just for an active browser window (e.g. the title bar colour), or if we're intending to apply it wherever a manifest is used (e.g. in OS shelf icons). If it's the former, then I think it's tractable (but still architecturally difficult) to use a CSS MQ since that code resides within the browser. If the latter, it means we need to find a way to translate the MQ condition out into every OS. While Chrome OS is probably easier since we control it, it isn't limitless -- we don't really want to put a CSS engine into the OS app service just to calculate theme colours.

Ideally we should limit the scope to dark/light for now with the option to expand in future. In discussing with Louise & Glen, Iā€™m convinced we can hard-code the support in lieu of bringing in the complete CSS engine.

As for the icons themselves, I am hopeful it can affect all icon instances. I do know that Windows and Mac support alternate theme icons (working on tracking down the details) so I would imagine that we could tailor the app package/representation to include those if they are defined (or create them if weā€™re talking SVG, which weā€™re actively working on, since SVG does support CSS user prefs too).

  1. Note that "override" is already a word (e.g. display_override); I don't think the spelling is a problem (this isn't one of those words that can be spelled two ways, "overide" is simply a misspelling, like "referer" lol).

If we do away with the nested structure and model this on the translations proposal, I think it simplifies things substantially and reduces the need to even declare something an "override". We could define a single override object in the manifest and define its algorithm, but leave the member definitions and such to the individual implementation (e.g., translations, user_preferences). So, for example:

{
  "translations": {
    "fr": {
      "name": "Bon chien",
      "description": "Une application pour chiens",
      "screenshots": []
    }
  },
  "user_preferences": {
    "color_scheme_dark": {
      "icons": []
    }
  }
}

In terms of processing the members of these override objects, only the allowed members could be redefined, and then within any array-of-objects members (e.g., icons, shortcuts), order would matter and devs could provide replacements for each whole object or only specific parts of an object (e.g., replacing the whole screenshot definition or only the accessible description of a screenshot member).

  1. I think we need to workshop the layout of the combined translations / color scheme further, but if anything, if we want to generalize it, I would look at generalizing the top-level object. You have translations / context and user-preferences / context, and I was suggesting to rename "context" to perhaps language and color-scheme so it's clear what "type" it has. If you want to generalize it, you might consider generalizing the top-level one to just alternatives (for example), with language and color-scheme as selectors inside it. This would potentially open up a can of worms allowing for alternatives with both a language and color-scheme selector -- I'm not sure it's worth allowing for combinatorial conditions like this, so my preference would be to keep the designs consistent, but separate: translations / language and user-preferences / color-scheme.

Totally agree on generalizing (see above), but I am wondering if we need the added complexity of translations and user_preferences being an array of objects rather than an object itself, where the "context" is the key name. Could defining the override object (as mentioned above) solve the potential complexity problem here? I guess thereā€™s still the potential that someone might have a dark/light icon with localized text somehow embedded in the icon (or screenshot), but I havenā€™t quite wrapped my head around how to solve for that yet.

The main difference between translations and user preferences is that order matters for user preferences but not translations. So the translations proposal wouldnā€™t suit user preferences unless we rely on the JSON object being ordered (which probably isnā€™t a good idea as discussed earlier in the thread). I think this context/redefine proposal works well for both.

As Thomas points out, order does matter for shortcuts and Iā€™d argue weā€™d want it to order for any array-of-objects where we are cherry-picking the bits to update (e.g., swapping only the accessible description on the screenshot rather than redefining the whole screenshots array).

loubrett commented 2 years ago

The ordering actually matters for "shortcuts".

I agree that order does matter for shortcuts. I was meaning the order of the user preferences. So if multiple preferences match, the order in which they are defined decides which override to use. This is discussed earlier in the thread. It isnā€™t a problem right now with just light and dark color schemes but could be an issue in the future. Whereas the ordering of languages doesnā€™t matter. For example it makes no difference whether ā€œfrā€ is defined before or after ā€œdeā€.

If we decide order isnā€™t important for user preferences, then I like the structure of the translations proposal.

MrAntix commented 2 years ago

Can you support css vars in the manifest? We already set our vars according to the dark/light preference and a use app overriding setting/preference

so something like ...

manifest.json
{
  ...
  "theme_color": "var(--theme-color)",
  "background_color": "var(--background-color)"
  ...
}
aarongustafson commented 2 years ago

Can you support css vars in the manifest? We already set our vars according to the dark/light preference and a use app overriding setting/preference

Adding custom property support in the manifest would likely introduce a significant amount of complexity from a parsing standpoint and from a rendering standpoint. Where would the custom props be defined? What happens if those definitions aren't loaded (e.g., stylesheet fails to load or JavaScript fails to execute)? There's also the question of the scope for these properties in terms of where they are defined and how they apply since they aren't contextual to a specific DOM node.

FluorescentHallucinogen commented 2 years ago

BTW, what about this? Don't beat me. :) This request is very similar to https://github.com/w3c/manifest/issues/892.

<link
  rel="manifest"
  href="./manifest.light.json"
  media="(prefers-color-scheme: no-preference), (prefers-color-scheme: light)"
/>

<link
  rel="manifest"
  href="./manifest.dark.json"
  media="(prefers-color-scheme: dark)"
/>
tomayac commented 2 years ago

BTW, what about this? Don't beat me. :) This request is very similar to #892.

<link
  rel="manifest"
  href="./manifest.light.json"
  media="(prefers-color-scheme: no-preference), (prefers-color-scheme: light)"
/>

<link
  rel="manifest"
  href="./manifest.dark.json"
  media="(prefers-color-scheme: dark)"
/>

See https://github.com/whatwg/html/pull/6444 and then https://github.com/whatwg/html/pull/6502, which reverted https://github.com/whatwg/html/pull/6444.

marcoscaceres commented 2 years ago

As an aside, we should bring back https://github.com/whatwg/html/pull/6444 ...

@FluorescentHallucinogen, you are not wrong... and I agree that should be supported (HTML spec issue).

However, we are going somewhat for developer convenience here. I think it does get a little unmanageable if you have to keep multiple manifest for both hreflang and media. For example:

<link
  rel="manifest"
  href="./fr/manifest.dark.json"
  media="(prefers-color-scheme: dark)"
  hreflang="fr"
/>

<link
  rel="manifest"
  href="./en/manifest.dark.json"
  media="(prefers-color-scheme: dark)"
  hreflang="en"
/>

And so on...

FWIW, I'm not sold on override object... I'd prefer just to keep a flat structure (at least, I'm not seeing any added value).

{
  "name": "Good dog", 
 "translations": {
    "fr": {
      "name": "Bon chien"
    }
  },
  "user_preferences": {
    "color_scheme_dark": {
      "icons": []
    }
  }
}

In terms or processing, "translations" should probably apply first, followed by "user_preferences". Having said that, we need to consider if certain things shouldn't be affected by user_preferences (e.g., the name and short_name). Similarly, an icon of the shortcut might change, but changing the shortcut's name would be weird.

It would also be strange if new icons/shortcuts appeared also in dark mode. So we would need to account for that.

aarongustafson commented 2 years ago

In terms of processing, "translations" should probably apply first, followed by "user_preferences". Having said that, we need to consider if certain things shouldn't be affected by user_preferences (e.g., the name and short_name). Similarly, an icon of the shortcut might change, but changing the shortcut's name would be weird.

@marcoscaceres In our proposals for user_preferences and translations we account for this, allowing for only specific properties of complex objects to be redefined in specific contexts. I actually just took a stab at walking through the complexities in the draft PR @loubrett and I are working on for user_preferences.

immortalcodes commented 2 years ago

Hi , I came here looking for a way to add this feature in my application, so till you have a proper fix , is there a temporary way to achieve this feature for defining a theme color for both light & dark modes

marcoscaceres commented 2 years ago

@immortalcodes, see https://github.com/w3c/manifest/issues/975#issuecomment-1109434065

(i.e., right now, you need two or more manifest ... but not all (any?) browsers support media="" on <link rel=manifest>... give it a try though and let us know!)

marcoscaceres commented 2 years ago

@aarongustafson, discussed this internally, and we'd like to propose going back to the media queries syntax. The rationale being that, at install time, the browser should take the possible MQ user preference values and convert them statically into something the OS understands (XML or whatever).

As we discussed, another issue was that we (well, me... my fault šŸ˜¬) had proposed essentially creating a new query/matching language for this. Feedback I got was, "yeah... cool idea... but please don't do that"... which is fair enough.

The one thing we do need to do, however, is talk to the CSS working group to see if we can solve "translations" as a user preference. Personally, I think that makes sense, as it's literally a system user preference, just like dark/light mode is. We would need to bake that into a media syntax somehow ("prefers-languages:" media feature or something).

Also, we are leaning strongly towards simple overrides for matches (even if they are more verbose). That is, if you declare an override, and it matches, that is what comes out at the end (even if the set of items in the override is not equal to what is declared in the root).

aarongustafson commented 2 years ago

Thanks for this @marcoscaceres! Iā€™d like to suggest we take a step back and come up with a set of principles to guide us in this effort. I have taken a stab at one such set over on the user_preferences discussion.

FWIW, I think the prefers-language/prefers-languages media feature is interesting. I do wonder what use case(s) it has, however. It seems like the Accept-Language header is a much more valuable signal and would allow for better performance through server-side negotiation rather than handling things at the layout & rendering layer.

marcoscaceres commented 2 years ago

FWIW, I think the prefers-language/prefers-languages media feature is interesting. I do wonder what use case(s) it has, however.

I was thinking:

  1. User browses the app in English and does not log in. For privacy reasons, the UA lies to the web page about the Accept-Language (always "en-US").
  2. User decides to install the app.
  3. The install prompt is presented and it is localized to match the actual OS preferred language.

It seems like the Accept-Language header is a much more valuable signal and would allow for better performance through server-side negotiation rather than handling things at the layout & rendering layer.

Right, but this signal is for use outside of the browsing context. Like with changing icons based on prefers-color-scheme and icons, it might also change dynamically if the user changes their OS (or app) language from system preferences.

marcoscaceres commented 2 years ago

Hi all, last week I took an action to consolidate all the solutions into a single proposal so we can evaluate the pros and cons and get a better understanding of what we are trying to do here. The result is at: https://github.com/w3c/manifest/issues/1045

Please take time to consider what is proposed there - there are a lot of "sharp edges and dark corners"! šŸ‘»

After evaluating all the different approaches, my conclusion was that building on @dcrousso's https://github.com/w3c/manifest/issues/975#issuecomment-832220101 proposal makes the most sense.

Would like to hear your thoughts, and if we agree, we can draft something up.

Akshat162001 commented 1 year ago

This approach makes sense to me ā€“

"theme_color": "red", "theme_colors": [ { "color": "darkred", "media": "(prefers-color-scheme: dark)" } ]

Authors could also choose to provide only the default:

"theme_color": "red",

Or (down the road) move to only using the longhand:

"theme_colors": [ { "color": "red" }, { "color": "darkred", "media": "(prefers-color-scheme: dark)" } ]

Hope it would work...

monecchi commented 3 months ago

Hi there! Any resolution regarding the proposed support? I really wanted to try it out in my pwa app! Thanks you all for the amazing logical structures proposed here!