Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reconsider Web App Manifest "theme_color" requirement #3891

Closed
laukstein opened this issue Nov 22, 2017 · 25 comments
Closed

Reconsider Web App Manifest "theme_color" requirement #3891

laukstein opened this issue Nov 22, 2017 · 25 comments

Comments

@laukstein
Copy link

Fallow the spec and recognize Web App Manifest theme_color parameter.
Currently showing error

grabilla g15072

Is related to #2466.

Spec https://w3c.github.io/manifest/#theme_color-member
Landed in Chrome 46 https://developers.google.com/web/updates/2015/08/using-manifest-to-set-sitewide-theme-color

https://www.chromestatus.com/feature/5709006190411776
It should be noted that if a theme color is specified as a meta-tag for a certain page (see https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android?hl=en), then the information from the meta tag will override the global theme color option in the manifest for that page.

@patrickhulce
Copy link
Collaborator

patrickhulce commented Nov 22, 2017

Currently we require that you supply both the theme_color property in the manifest (the one you've linked) and the theme-color meta-tag. The error is telling you that you have one but not the other.

Could you clarify what you mean by 'recognize'? Is there information you feel is missing from the documentation?

@laukstein
Copy link
Author

@patrickhulce why would there be a reason to require both?
Both does the same, except the meta-tag theme-color would rewrite manifest theme_color based on spec. There are no good reason to have both, except when meant to rewrite the default property.

Currently only Chrome and Firefox behind flag manifest.install.enabled supports Web App Manifest, and both says supporting theme_color, what means no need for theme-color meta-tag.

I think documentation must be fixed to and require only one of properties, and also mention that valid theme-color would rewrite theme_color value.

Can you fix it?

@laukstein
Copy link
Author

@patrickhulce does #3891 still needs-more-info?

@patrickhulce patrickhulce changed the title Recognize Web App Manifest "theme_color" Remove Web App Manifest "theme_color" requirement Nov 27, 2017
@patrickhulce patrickhulce changed the title Remove Web App Manifest "theme_color" requirement Reconsider Web App Manifest "theme_color" requirement Nov 27, 2017
@patrickhulce
Copy link
Collaborator

@laukstein meta tag should enable the coloring of the address bar on first load before the manifest has been loaded, so it seems reasonable to include it on PWA entry pages when the assumption is the user is visiting on a mobile connection where network contention may delay a low priority request such as the manifest (if you see evidence to the contrary we'd love some examples!). Even though it overrides the manifest value, it still makes sense to have a sensible default of a theme color that applies to the entire web app when the meta tag is not specified on every single page (ones that are assumed to be visited after the manifest has been loaded).

I hope this helps explain the current rationale for the policy, but we appreciate the feedback!

cc @vinamratasingal @tjsavage for FYI of feedback to take into account for PWA checklist

@paulirish
Copy link
Member

Looking at the chromium source now, the earliest the manifest is fetched on a new site is after onload. It also won't fetch the manifest unless the site has sufficient engagement.

The meta tag allows the browser to color the address bar earlier than that point.

So it does seem to be correct that we still require this meta tag.

@laukstein
Copy link
Author

@paulirish @jakearchibald why to delay manifest download until page onload, etc.? Why not async - load manifest immediately when detected in HTML without blocking continuous HTML and its content?

When Webapp is on homescreen/desktop, is manifest fetched from cache or from website blocking the website load, or else?
Why even to fetch manifest if Webapp isn't on homescreen/desktop? How it would benefit?

Maybe when Webapp is on homescreen/desktop, Lighthouse mustn't require theme-color if having theme_color in manifest? Otherwise require meta-tag theme-color because manifest isn't jet fetched.

@patrickhulce
Copy link
Collaborator

patrickhulce commented Dec 7, 2017

I'm not sure I understand your current proposal @laukstein.

Maybe when Webapp is on homescreen/desktop, Lighthouse mustn't require theme-color if having theme_color in manifest?

Lighthouse and users visit the page before it's been put on the homescreen, in this scenario, you'd want the theme-color meta tag present to color the address bar, so it seems reasonable to make sure you specify theme-color via meta tag.

Since this is a PWA audit and you're already serving a manifest in the PWA case, you'd want the same theme_color to cover any pages you visit in the context of our application that don't have the meta tag, so it seems reasonable to make sure you also specify theme_color via the manifest.

If your entire application is a SPA that never visits any other page then the manifest version will be superfluous, but I don't see why we'd want to not enforce the meta tag which seems to be your primary argument. Maybe I'm misunderstanding?

@laukstein
Copy link
Author

@patrickhulce, hi! The issue I think is how manifest download is handled,

@paulirish: Looking at the chromium source now, the earliest the manifest is fetched on a new site is after onload. It also won't fetch the manifest unless the site has sufficient engagement.

and till it changes, likely theme-color is required (would avoid flicker) and that case theme_color is unnecessary.

@patrickhulce
Copy link
Collaborator

I see, so you do not have an issue with requiring both theme-color in meta and manifest anymore then? Is it just that you would like the behavior for when the web app manifest is downloaded by Chrome to change?

If this is the case, you can file a bug with Chromium detailing your use case and why the behavior should be different though as Chrome is following the advice in the spec, I'm not sure it's likely to change.

To obtain a manifest, the user agent MUST run the steps for obtaining a manifest. The appropriate time to obtain the manifest is left up to implementations. A user agent MAY opt to delay fetching a manifest until after the document and its other resources have been fully loaded (i.e., to not delay the availability of content and scripts required by the document).

If I still misunderstood, perhaps a thorough read of the web app manifest spec might prove helpful to you since it details the need for an improvement on meta tags (and why we recommend putting theme_color in your manifest), and why meta tags are still necessary in the interim (and why we still recommend using theme-color in meta).

@brendankenny
Copy link
Member

Sounds like this isn't necessarily a Lighthouse bug, and is more of an issue with how browsers treat the two theme colors. If you're still seeing a problem with Lighthouse's behavior, though, please comment and we can reopen.

@clshortfuse
Copy link

clshortfuse commented Aug 28, 2019

I think the requirement should be removed or tweaked to wait until the load event. The problem is that now that browsers can support Dark/Light color schemes. But manifest.json only supports a single color. For my clients, I'm dynamically changing the value of "theme-color" based on the user's color-sheme preference.

For a real example, I have a prerender script that runs before the page renders (in DOMContentLoaded event)

  if (window.matchMedia('(prefers-color-scheme:dark)').matches) {
    setMeta('apple-mobile-web-app-status-bar-style', 'black-translucent');
    setMeta('theme-color', '#000000');
  } else {
    setMeta('apple-mobile-web-app-status-bar-style', 'default');
    setMeta('theme-color', '#ffffff');
  }

In the code example, I'm using pure black and white, but it could easily be dark blue and light blue, etc.

On a side-note, I've already added color scheme support with the background by using "background_color": "rgba(0,0,0,0)". Android OS will show the splash as grey/black on Dark Mode and white on Light Mode. I haven't tried using transparent as the theme_color, but I feel like that would be wrong. I would rather, intentionally, use the system default.

Edit: Lighthouse reads transparent as not configured for background_color and theme_color, so I feel that's a bug.

@patrickhulce
Copy link
Collaborator

@clshortfuse which requirement are you referring to? I'm not sure how either are failing to wait for the load event. In fact, the discussion above is based around frustration that they're not firing earlier than the load event.

The example you've shown should absolutely be respected by the meta[name=theme-color] audit. Please file a separate bug if it's being ignored completely.

Lighthouse reads transparent as not configured for background_color and theme_color, so I feel that's a bug.

It very well might be a bug, would be willing to file a separate bug with a repro URL?

@laukstein
Copy link
Author

I think @clshortfuse is referring to spec issue w3c/manifest#758

color_scheme API proposal

"icons": [
  {
    "src": "/icons/play-later.svg",
    "type": "image/svg+xml",
    "purpose": "any",
    "color_scheme": "no-preference"
  },
  {
    "src": "/icons/play-later-reverse.svg",
    "type": "image/svg+xml",
    "purpose": "any",
    "color_scheme": "dark"
  }
 ]

@clshortfuse
Copy link

clshortfuse commented Aug 28, 2019

@laukstein That's for the icons, but I'm focusing on theme_color itself. But I'm getting failures even though I'm setting theme-color attributes in <head> (and another when I use "background_color": rgba(0,0,0,0)" in the manifest).

I had understood that it's an automatic failure if it's not in the manifest, but it looks like it should pass if I set the theme-color attribute. I just don't a reproducible link yet, but I'll be filing the issue once I do.

@patrickhulce
Copy link
Collaborator

Oh, it is a requirement to set theme_color in the manifest as well please do not file a separate issue for that. I thought based on your comments about waiting for load that LH was failing to pickup your meta[name=theme-color].

@clshortfuse
Copy link

clshortfuse commented Aug 28, 2019

@patrickhulce Okay, let's just clarify this. I'm getting:

Does not set an address-bar theme color

Under that, the failure says:

Failures: Manifest does not have theme_color.

But I am setting it on DOMContentLoad via setting the head attribute. I have a reproducible link at https://family.taximachine.com/app

I'm also getting which may or not be related:

Is not configured for a custom splash screen

Failures: Manifest does not have background_color, Manifest does not have theme_color.

Even though background_color is actually present and set to rgba(0,0,0,0).

@patrickhulce
Copy link
Collaborator

patrickhulce commented Aug 28, 2019

But I am setting it on DOMContentLoad via setting the head attribute. I have a reproducible link at https://family.taximachine.com/app

That page is setting a meta[name=theme-color] on DOMContentLoad, not the theme_color in the manifest. This message is expected and WAI. The discussions above detail why the audit requires setting both values.

tl;dr - you want the OS theme color in app switchers, etc to match that of your theme-color established by the meta tag.

For your specific situation, it's not a hard requirement for them to match though so you can put the OS-specific value in here if you want and rely on the meta override you currently have for the address bar. Maybe you could serve a dynamic manifest if this is functionality you really want to support across the board though?

Even though background_color is actually present and set to rgba(0,0,0,0).

This does indeed seem like a bug in our version of color parser :) (FWIW, it's just being a little too strict rgba(0%, 0%, 0%, 0.0) passes the check)

@clshortfuse
Copy link

clshortfuse commented Aug 28, 2019

Thanks for taking a look.

So I guess I'd agree with reducing the requirement. The title states: "Does not set an address-bar theme color" when it does, so the language is confusing off the bat. It is being set, just not via the manifest.

I can understand that browsers shouldn't be required to execute some JS in order to find out what theme-color to use. And, as I stated, I intentionally want to browser to provide its own preference if that is the case, so there could be valid reason to not provide a value in the manifest. But even so, on the latest Android Q beta with Chrome, changing from Dark Mode to Light Mode on the OS changes the app switcher will update the color as well. So Chrome is reading the meta tag. I don't see a use case for theme_color over the manifest since it's not easily configurable at runtime.

For my purposes I reason that it's better to use the meta tag, so I think it would be better if a warning (not failure) was emitted if one of the two are missing, rather than a failure if only one is missing.

I could probably add the theme_color values int two separate manifests, and do <link ref="manifest" href="manifest-dark.json" media="(prefers-color-scheme:dark)"> to provide a fallback, though it seems like it would just be made to satisfy Lighthouse, not any real-life application.

And then there's use case to consider. Suppose you you don't want to provide any color and let the browser provide one. I do this for background_color intentionally already and, because of lack of an official spec, I'm using transparent. It works great, because the splash screen on Android is now managed by the system (again intentionally so). theme_color, while not as obvious a splash background, could also follow the same logic. (I'm actually only really setting the meta tag so it matches the in-page appbar, but if I didn't have one, I'd just let the system pick.)

So, I'm using rgba(0%, 0%, 0%, 0.0) as a "hack" of sorts for both theme_color and background_color and Lighthouse seems okay with it. I'm just worried about what issues may arise later from that. (I don't have an iOS device on IOS 13 to test their dark mode implementation.) So because there is a use case for intentionally not providing one, I think it should be relaxed to a warning.

If, on the other hand, W3C were to incorporate support for specific value to say "system-default" then I can see Lighthouse considering it as a failure. (Maybe they can add"transparent" as default in the spec.) But then again, I can easily see them say, if you want the default, don't set one.

@patrickhulce
Copy link
Collaborator

These are all good points. I'm inclined to reduce the requirement to specifies theme-color, warn if theme_color is not set and just documenting why we suggest setting both.

Does anyone else on LH disagree?

@patrickhulce patrickhulce reopened this Aug 28, 2019
@brendankenny
Copy link
Member

I'm inclined to reduce the requirement to specifies theme-color, warn if theme_color is not set and just documenting why we suggest setting both.

I think I'd be ok with this, but mostly because I personally don't think omnibox colors are that important to a PWA experience :)

But I think several of us may be biased that way, so we might need to invoke the ⚡🧙PWA checklist council 🧙⚡to make a real ruling (the possibility for change is higher since this is on the polished list and not the base PWA requirements).

I believe the reasoning was something about a flash of unstyled omnibox before the html loads when launched as an installed app? If the goal is a good startup experience (and dynamically changing the theme-color later is out of scope), another option is to go back to the check of the meta theme-color and the manifest theme_color matching, but using only meta theme-color defined in the html, not added dynamically.

  • If neither the html or the manifest defined a theme color, that would also count as matching?
  • Any dynamic changes after that would be up to the app and Lighthouse would ignore.
  • We'd need to augment the MetaElements gatherer to tell how the elements ended up in the DOM.

There may also be webapp manifest spec changes that could be made to deal with changes in the ecosystem, e.g. ability to specify light/dark modes (w3c/manifest#779 and w3c/manifest#758), a default color (the spec-defined default undefined can't be used in json but as mentioned in comments above just leaving it out does this), etc.

@laukstein
Copy link
Author

FYI, Chrome canary (https://bugs.chromium.org/p/chromium/issues/detail?id=578122) supports now prefers-color-scheme in SVG also used in App Manifest:

<!-- https://blog.tomayac.com/2019/09/21/prefers-color-scheme-in-svg-favicons-for-dark-mode-icons/ -->
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
  <style>
    circle {
      fill: yellow;
      stroke: black;
      stroke-width: 3px;
    }
    @media (prefers-color-scheme: dark) {
      circle {
        fill: black;
        stroke: yellow;
      }
    }
  </style>
  <circle cx="50" cy="50" r="47"/>
</svg>

Would result in light mode:
grabilla g23904

and in dark mode:
grabilla g18468

Tested on desktop.

@donno2048
Copy link

Currently we require that you supply both the theme_color property in the manifest (the one you've linked) and the theme-color meta-tag. The error is telling you that you have one but not the other.

Why is this a requirement?

@jfbrennan
Copy link

jfbrennan commented Jul 31, 2023

Who is it that feels the need to dictate to the entire population of web designers that their PWA must override their users' OS window color to match some imagined PWA theme? If designers want to, by all means, but it seems ridiculous for Lighthouse to be reporting your PWA is not a valid PWA because you haven't yet smothered the Chrome address bar with some brand color.

Please remove this arbitrary requirement from the PWA validation checks.

@connorjclark
Copy link
Collaborator

connorjclark commented Jul 31, 2023

it seems ridiculous for Lighthouse to be reporting your PWA is not a valid PWA because you haven't yet smothered the Chrome address bar with some brand color.

This framing is definitely a stronger assertion than what we intend with our report, given it's in the PWA Optimized section of audits. It's looser than "this PWA is not valid". But I see your point - we shouldn't be forcing people to use an optional feature of PWAs as arbitrary as color theming.

I think we should consider doing what Brendan laid out here: #3891 (comment) only check for the problematic flash-of-colors when the PWA manifest and the meta element theme colors disagree.

@adrianaixba
Copy link
Collaborator

As per Chrome’s updated Installability Criteria, Lighthouse will be deprecating the PWA category in the next upcoming release. For future PWA testing, users will be directed to use the updated PWA documentation. Marking this as closed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants