A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

[Proposal] Night Mode API

LiuBoJie
2016-11-29

**Problems:**As mobile devices become more and more popular for people to access the Internet, browsing under poor light condition happens more frequently in our daily life. However, CSS of most websites were designed for well lit environment, like dark text with white background. The contrast leads to uncomfortable experience for user to surf the Internet under such circumstance.

Proposal: Here is to propose a solution which provides a way in which web page can be notified of light conditions from browser and change its CSS accordingly. More details please refer to the explainer doc. The following is selectively extracted from the explainer.

API Here is to propose a solution which builds connection between web page and browser side. Browser notifies page of “colormodechanged” event when user switches day/night mode in the UI of browser. Then page side calls the registered event listener to perform changes of style by its own CSS and JS.

  • The ColorModeChangedEvent IDL: Noted that the attribute “colortheme” is defined either “normal” or “night” by browser side.
[Constructor(DOMString theme)]
interface ColorModeChangedEvent : Event {
    readonly attribute DOMString colortheme;
};
  • Due to some browsers have implemented browser-side night mode as mentioned above. Web page has to define a special <meta> to inform browser whether it is using the Night Mode API or not:
<meta name=”x5-colormode” content=”x5-nightmode”>
  • (optional) If web page wants to query current “colortheme”:
window.colortheme
  • (optional) In case browser takes time in recalculating style, repainting, etc. after the listener was run. A new pseudo-class could be added on some elements and browser would first select the styles in pseudo-class in night mode and performs a quick refreshing. However, the pseudo-class needs to be supported by browser engine.
:-x5-colormode-night

Usage The following is a simple example using Night Mode API. It works in QQBrowser for Android. There is an apk provided in github.

<html>
<head>
	<meta name="x5-colormode" content="x5-nightmode"/>
	<script>
	window.addEventListener('colormodechanged', function (evt) {
		if (evt.colortheme === 'night') {
			document.documentElement.className += "G-night"
		} else if (evt.colortheme === 'normal') {
			document.documentElement.className -= "G-night"
		}
	});
	</script>
	<style>
		.G-night {background-color:yellow;font:black;}
		.G-night:-x5-colormode-night {background-color:white;font:red;}
	</style>
</head>
<body class="G-night">
	Hello World!
</body>
</html>
jpdevries
2016-12-01

What does this offer that the HTML5 Ambient Light API doesn’t? Seems like it is a meta tag at the expense of granular control over how much light is detected.

LiuBoJie
2016-12-06

It looks mostly the same, as you said. The HTML5 Ambient Light API provides a solution for poor-light browsing. Moreover, the Night Mode API, should be called “Color Mode API” more exactly, can notify pages of different color modes. But I am not sure whether it is useful or not. As for the meta tag. It is a choice for pages to or not to validate the Night Mode API.

Nexii
2016-12-06

Wouldn’t a @media condition be able to express this better? (Not to mention designed to be able to express different viewing conditions and/or modes)

LiuBoJie
2016-12-16

In my opinion, the switch between different modes is more a user action than a browser action invoked automatically.

tomhodgins
2017-01-09

I’ve experimented with the idea of grabbing the hour based on the user’s clock setting, and then either flipping the colors of the site between black-on-white for ‘day’ mode and white-on-black for ‘night mode’. Here’s the first example:

<style>
  @element 'html' {
    $this {
      color: eval('sunny ? "black" : "white" ');
      background: eval('sunny ? "white" : "black" ');
    }
  }
</style>

<script>
  var hour = new Date().getHours()
  var sunny = (7 < hour && hour < 19)  
</script>

And to further the idea of time-based color themes, I also used JavaScript to ask the user’s set time to fake the same kind of blue-light-killing orange overlay like Flux or Night Shift, to create a night mode for websites. The EQCSS for that is here:

<style>
  @element 'html' {
    :root:before {
      content: '';
      position: fixed;
      width: 100%;
      height: 100%;
      background: rgba(255,175,0,eval('amount / 20'));
      mix-blend-mode: multiply;
      pointer-events: none;
      z-index: 9999;
    }
  }
</style>

<script>
  var hour = new Date().getHours()
  var night = (hour < 7 || 20 < hour)
  var amount = night ? (20<hour ? hour%20 : hour+4) : 0
</script>

And a live demo is here: http://codepen.io/tomhodgins/pen/VPwGPG

Could a setting for a style like this be something that a user sets on the website, rather than there being a ‘night mode’ event for turning night mode on?

I imagine a website like Reddit where people have accounts, and are expected to spend a long time reading could add a time-based night mode for users and allow them to enable or disable this feature for their own account across all devices.

It’s a little different than what you’re proposing here, but I’m curious about this feature and what would make it useful. Is there already a standardized way to tell is night mode is on in Android or iOS natively for app development and this mimics that in the browser as well? If night mode is set at the device level, what style changes would you want to make to websites to help when night mode was activated?

LiuBoJie
2017-01-17

I think time-based implementation is inspiring and provides more real-time presentation for users. As for the questions, I try to answer it based on my limited knowledge.

I am not sure if the time setting is provided by webpage or browser. If is by webpage, every website with night mode feature would do extra coding for setting logic and UI design in exchange of cross platform benefit. Is there a way to integrate your idea with my proposal? Let browser inform webpage of ‘night mode’ event with the timing, then webpage do the changes and record current mode into personal account. As a result, webpage wouldn’t bother to the setting things.

As far as I know, only ‘Night Shift’ on iOS provides relative function. And it only changes the overall color of screen. In addition, some browser vendor’s night mode can be found here.