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

New feature proposal: add support for media attribute to <meta name="theme-color"> #6495

Closed
dcrousso opened this issue Mar 15, 2021 · 15 comments · Fixed by #6569
Closed

New feature proposal: add support for media attribute to <meta name="theme-color"> #6495

dcrousso opened this issue Mar 15, 2021 · 15 comments · Fixed by #6569
Labels
addition/proposal New features or enhancements

Comments

@dcrousso
Copy link

The current spec for obtaining the page's theme color allows for only one color value to be "returned" for use by the user agent. This means that there's no declarative way for a developer to adjust the theme color of their site depending on the state of the user agent or display device. This results in situations where the site only looks good when the user agent state or display device initially matches what's expected by the page. As an example, if the page assumes that light mode is the initial/default state and the user has already enabled system-wide dark mode, then the theme color could be painfully bright and would contrast/conflict with the rest of the system.

It would be great for developers (and also possibly web crawlers) to be able to have <meta name="theme-color"> support a media attribute similar to link. For example,

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

As far as compatibility, the algorithm for obtain the page's theme color is a "first pass" system which will return as soon as a valid <meta name="theme-color"> is found in tree order. Since this feature is entirely opt-in, it's possible for a developer to preserve the existing behavior of something like

<meta name="theme-color" content="red">

by making sure that it is the first <meta name="theme-color"> in tree order and have any alternates come after

<meta name="theme-color" media="(prefers-color-scheme: light)" content="red">
<meta name="theme-color" media="(prefers-color-scheme: dark)"  content="darkred">
<meta name="theme-color" media="(prefers-contrast: less)"      content="...">
<!-- etc -->
@annevk annevk added addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest labels Mar 15, 2021
@domenic
Copy link
Member

domenic commented Mar 15, 2021

This seems somewhat reasonable, but I suspect it'd be better to approach this holistically as part of making all the app manifest properties (such as screenshots, background color, splash screen, etc.) color-scheme aware. So I suspect this would best be tackled by opening an issue at https://github.com/w3c/manifest/. Then <meta name="theme-color"> can continue to only be used for simple cases.

Additionally, please note https://whatwg.org/faq#adding-new-features : it's best to start with a use case, not a solution. In this case your use case appears to be dark mode vs. light mode, so that points toward something less general than the full power of media queries.

@jensimmons
Copy link

jensimmons commented Mar 15, 2021

This is something we are very interested in, as implementors. @dcrousso is a browser engineer.

It would be good to make all the app manifest properties color-scheme aware. But it also makes a great deal of sense to provide a mechanism for developers to define a theme color for both dark and light modes using the lightweight <meta name="theme-color"> in HMTL alone.

Most websites are not “web apps” and do not have a manifest file. Requiring a manifest file to define a dark mode theme color while supporting light mode theme color in HTML does not make sense.

Rather than punting on this, we'd love to have a discussion about what syntax might be best.

@dcrousso
Copy link
Author

Also, unless I'm misreading this

[...] a document may override the default theme color through the inclusion of a valid [HTML] [meta
(https://html.spec.whatwg.org/multipage/semantics.html#the-meta-element) element whose name attribute value is "theme-color".

that seems to suggest that the <meta name="theme-color"> in HTML takes precedence over anything specified in the manifest.

I'd also like to avoid having situations where network latency causes there to be a color change flash (see the example I describe in the issue description above).

@mirisuzanne
Copy link

I like this proposal.

In most cases I would not want to add an entire manifest just to handle basic theme issues like light/dark mode. If I had a manifest anyway, that would be fine - but I have many sites & apps using color themes without needing a full manifest. In fact, I don't know how to use a manifest, but I do understand how to use this meta-tag with media queries after a quick glance.

  • Media queries are the tool I use to establish a color scheme normally, so they are what I would expect to use here.
  • Since I can define the default in a meta-tag it would be great to provide some variations using the same syntax.

I do think @domenic hints at an important question about which media queries are allowed? Are we talking about a limited set of color-related preferences, or all media queries? And what are the use-cases?

  • Clearly it's not limited to prefers-color-scheme, since you also show prefers-contrast in your example.
  • I would likely combine thoes as well, if I was using both: (prefers-contrast: less) and (prefers-color-scheme: light)
  • Much less common, but some sites do change backgrounds & colors based on other media queries, like size or orientation. Why not allow the theme-color to adjust using those same queries?
@malchata
Copy link

Are there any issues with adding media to the HTMLMetaElement's interface? As far as I can tell, it doesn't exist on the <meta> element as-is, and maybe there's no practical concern.

Another thing I'm curious about is the evaluation of other non-prefers-color-scheme media queries that may not be applicable to <meta> elements (e.g., min-width, prefers-reduced-data, etc), but that's probably a non-issue.

In principle, I'm all for this, and I think it'd be a great addition to the platform.

@jensimmons
Copy link

I think one of the big questions at hand is — are media queries as an HTML attribute the right solution? Or would a different keyword / different attribute on the <meta> tag be better? It seems more complex to use media, because media queries do a lot of things. But also, media is more in line with the rest of HTML — not something weirdly bespoke / different syntax or concepts than what works in elsewhere CSS.

@malchata
Copy link

malchata commented Mar 15, 2021

I think the consistency of media would be better, but I'm not a browser engineer and I have no insight into the feasibility of such a lift. There could be some as-of-yet undiscovered issues by adding media to <meta>. For example, could meta descriptions influence search crawlers if their media attribute includes a min-width media query? Does that open up new potential issues with SEO?

@fantasai
Copy link
Contributor

fantasai commented Mar 15, 2021

While using media here seems like a natural fit, I'm a little concerned about what happens when someone tries to use it on a different type of meta tag. If we define it to only work on theme-color now, we'd have to be careful if we want to make it apply to other meta in the future in case some sites have stray media attributes on other tags. If we make it work on everything, we'd have to think about where we need exceptions that make it not apply, e.g. charset or viewport.

But whichever way you go, if you're going to apply media queries syntax, then allow the full set of queries. Limiting it seems unnecessary, and probably means making special exceptions just for theme-color in the browser code that evaluates them.

@annevk
Copy link
Member

annevk commented Mar 16, 2021

It seems fine to extend meta in the same way as link, where we add attributes for specific identifiers and other identifiers could adopt them as needed (but not have them from the get-go).

(And speaking of web manifest, I think #6444 was a mistake as per mozilla/standards-positions#500 and web manifest should instead tackle media considerations on a per-feature basis, as this proposal does.)

@tabatkins
Copy link
Collaborator

In this case your use case appears to be dark mode vs. light mode, so that points toward something less general than the full power of media queries.

While I expect that color-scheme would be the most common reason to change this, the contrast MQs are also relevant, letting you flip to a more consistent color for less and a starker black or white for more. Anything that an author would depend on to change their page's background color fits here, since the point of theme-color is to match the UI color to, generally, the page's BG color (or sometimes an accent color, but that's related to the bg color, so same principle applies)

While most of the existing MQs wouldn't be particularly useful here, there are enough of them that a bespoke mechanism reproducing a subset of them seems like a waste of time and spec complexity. We've already got a mechanism for expressing and selecting based on user preferences, so we should just reuse it.

I suspect it'd be better to approach this holistically as part of making all the app manifest properties (such as screenshots, background color, splash screen, etc.) color-scheme aware

Yup, several of those properties should be MQ-aware as well (for the same reasons as above, not just color-scheme-aware). That looks like a problem that would be at least slightly more difficult to solve (refactoring the syntax of the manifest object) vs applying the media property here, and as well, unless we're deprecating theme-color in favor of recommending only using a manifest, I don't think it's reasonable to give the two significantly different powers unless there's a decent gulf in complexity between the two (which I don't think applies here).

@hober hober linked a pull request Apr 9, 2021 that will close this issue
3 tasks
@hober
Copy link
Collaborator

hober commented Apr 9, 2021

I gave a go at writing a PR for this in #6569. I'm sure I missed plenty of nuance from the conversation here; please take a look and help me fix it! :)

@adactio
Copy link

adactio commented Jun 15, 2021

This might well be a silly question but I figured I'd ask anyway...

From an implementor perspective, how hassle-ish would it be to parse the value of the content attribute as CSS? In particular, how much of a pain would it be to allow the content attribute to contain custom properties?

I know that would mean that the value wouldn't resolve until style sheets have been loaded and parsed, but that's also true of the background colour of the document so in theory everything should resolve at the same time (unlike the discussion around the web app manifest which might be fetched and parsed asynchronously).

The use case here—which, I admit is very niche—is having a single site or document with multiple stylesheets (each one potentially having its own light and dark mode).

The other use case is when the theme colour changes to match the content of the page (Jen showed the example of an e-commerce store that updates the theme colour based on the colour of the item you're looking at). That's currently possible using JavaScript in a kind of brute-force way (updating the DOM node of the meta element to change its content value) but having a declarative option, via custom properties, would be sweet!

@tomayac
Copy link

tomayac commented Jun 15, 2021

Can't you just do the following:

<link rel="stylesheet" media="(prefers-color-scheme: dark)" href="dark.css" />
<link rel="stylesheet" media="(prefers-color-scheme: light)" href="light.css" />

This will on-the-fly swap the applied CSS when the color scheme changes.

The idea is to enable the same for <meta name="theme-color">, so you exactly don't have to JavaScript it.

@adactio
Copy link

adactio commented Jun 15, 2021

That wouldn't solve either of the use cases I mentioned. Sorry if I wasn't clear: I wasn't talking about a site having two stylesheets, one for dark and one for light. I was talking about a site having many, many stylesheets (in a Zen Garden kind of way). On my site, for example, I have multiple style sheets for different theming and each one might have it's own media queries for dark and light mode.

And for the situation where the theme colour changes to match the contents of the page, JavaScript is currently the only way to do it (that's unrelated to dark and light modes though).

@tomayac
Copy link

tomayac commented Jun 15, 2021

Oh, I see. You mean schemes not exposed by a media query. So you could have a "summer" scheme (whatever that may look like), which has a dark and a light variant. Gotcha. Yeah, in this case you need to JavaScript it.

@whatwg whatwg deleted a comment from Sohail1088 Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements