lighthouse
lighthouse copied to clipboard
Reconsider Web App Manifest "theme_color" requirement
Fallow the spec and recognize Web App Manifest theme_color
parameter.
Currently showing error
Is related to https://github.com/GoogleChrome/lighthouse/pull/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.
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?
@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?
@patrickhulce does #3891 still needs-more-info
?
@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
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.
@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.
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?
@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.
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).
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.
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.
@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?
I think @clshortfuse is referring to spec issue https://github.com/w3c/manifest/issues/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" } ]
@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.
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]
.
@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 havetheme_color
.
Even though background_color
is actually present and set to rgba(0,0,0,0)
.
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)
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.
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?
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 (https://github.com/w3c/manifest/issues/779 and https://github.com/w3c/manifest/issues/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.
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:
and in dark mode:
Tested on desktop.
Currently we require that you supply both the
theme_color
property in the manifest (the one you've linked) and thetheme-color
meta-tag. The error is telling you that you have one but not the other.
Why is this a requirement?
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.
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: https://github.com/GoogleChrome/lighthouse/issues/3891#issuecomment-526838978 only check for the problematic flash-of-colors when the PWA manifest and the meta element theme colors disagree.
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!