Enabling Dark Mode On Websites Based On Surrounding Light
Ananya Neogi

Ananya Neogi @ananyaneogi

About: Frontend dev amongst other things.

Location:
localghost:3000
Joined:
Oct 9, 2018

Enabling Dark Mode On Websites Based On Surrounding Light

Publish Date: Jan 4 '19
282 28

Now you can switch between a "dark mode" and "normal mode" on a website based on the surrounding light! It can really help in curating a better user experience based on the conditions users are viewing your website.

So, here's how you do it-

Adding the short and simple javascript.


if ( 'AmbientLightSensor' in window ) {
  const sensor = new AmbientLightSensor();
  sensor.onreading = () => {
    console.log('illuminance level :', sensor.illuminance);
      if(sensor.illuminance < 15) {
            document.querySelector('body').classList.add('dark');
      }
      else {
            document.querySelector('body').classList.remove('dark');
      }
  };
  sensor.onerror = (event) => {
    console.log(event.error);
  };
  sensor.start();
}

Enter fullscreen mode Exit fullscreen mode

Then, add specific css for your dark mode under the class you've just set. Like here I am adding and removing the class dark based on the level of ambient light.
You can play around with the illuminance value and see what works better in your case.

I also found this cool experiment by @tomlokhorst, where he changed font weight based on ambient light using variable fonts.
However, he mentions further in the thread that he did not use the aforementioned AmbientLightSensor but it still makes a pretty good use case.


Disclaimer: The browser support for this feature is low.
On chrome it's only available under a flag. Check the caniuse stats for more details. Despite that the future of web is bright or in a dark mode, however you like it! :)

EDIT-
If you're getting an error, something like AmbientLightSensor does not exist on type Window while trying to make this work in Angular, refer to this comment for a solution.

Reference

Comments 28 total

  • Ben Halpern
    Ben HalpernJan 4, 2019

    Woah!

  • Tyler V.
    Tyler V.Jan 4, 2019

    This is pretty nifty! It'll be super cool once this is more available! :D

  • Andy Zhao (he/him)
    Andy Zhao (he/him)Jan 4, 2019

    WHAT THE HECK that's amazing! I wonder how the browser detects the light???

    • Andrew Bone
      Andrew BoneJan 4, 2019

      It relies on the device having a sensor.

      developer.mozilla.org/en-US/docs/W...

      • Andy Zhao (he/him)
        Andy Zhao (he/him)Jan 5, 2019

        Ah, okay. For some reason I thought it was solely based on software.

    • Saulo Vargas
      Saulo VargasJan 5, 2019

      Usually cellphones or some notebooks have hardware to detect light and auto-adjust brightness, so it can be used for this.

      • Ananya Neogi
        Ananya NeogiJan 5, 2019

        Yes, this is based on the sensors that are present on your device. The Sensors API exposes those device sensors on to the web platform.

    • Ananya Neogi
      Ananya NeogiJan 5, 2019

      It is based on the Sensors API.
      Also, to use this sensor, browser needs permission from the user, that is done via the Permissions API.

  • Antony Garand
    Antony GarandJan 5, 2019

    Very nice!

    I'll try making a POC where the website becomes progressively darker based off the illuminance level, using css custom properties, if anyone is interested in joining me!

    If someone wants to out the snippet using a real website, Brawldb is dark by default, but light when the body has the theme-light class.

    It is usually toggled via the top-right menu, but should also work via this snippet.

    • Ananya Neogi
      Ananya NeogiJan 5, 2019

      Definitely, go for it! :)

      I also made a very simple demo web page sometime back. Check that out, if you wish, to see this code work instantly.

  • Jorge Ramón
    Jorge RamónJan 5, 2019

    OMG thats crazy!!

  • MsumanP-hexaware
    MsumanP-hexawareJan 5, 2019

    How can i implement the same in angular ?
    I tried but Its giving error.

    • Ananya Neogi
      Ananya NeogiJan 5, 2019

      This is just plain JavaScript so it should work. Can you elaborate what error it is?
      Maybe it's something specific to angular and not related to this particular bit of code.

      • MsumanP-hexaware
        MsumanP-hexawareJan 5, 2019

        I am getting error like Property 'AmbientLightSensor' does not exist on type 'Window' & Cannot find name 'AmbientLightSensor'.

        My Code:
        if (window.AmbientLightSensor) {
        const sensor = new AmbientLightSensor();
        sensor.onreading = () => console.log(sensor.illuminance);
        sensor.onerror = event => console.log(event.error.name, event.error.message);
        sensor.start();
        }

        • Ananya Neogi
          Ananya NeogiJan 5, 2019

          You need to extend the existing Window interface to tell it about this new property.
          So, before your class implementation add this code -

          declare global {
              interface Window {
                  AmbientLightSensor: any;
              }
          }
          

          Then you can add your AmbientLightSensor code in the following way -

                  if (window.AmbientLightSensor) {
                      const sensor = new window.AmbientLightSensor();
                      sensor.onreading = () => console.log(sensor.illuminance);
                      sensor.onerror = event => console.log(event.error.name, event.error.message);
                      sensor.start();
                  }
          

          I hope this will solve your problem.

          • MsumanP-hexaware
            MsumanP-hexawareJan 5, 2019

            Now error is not coming but window.AmbientLightSensor is coming as undefined.

  • smakosh
    smakoshJan 5, 2019

    Implementing this right away! thanks for sharing

  • XYZ
    XYZJan 6, 2019

    If there is no sensor available then you might also just use the local time. Maybe not for a complete dark mode but for something like a night shift mode. The same way the OSs are doing it.

  • Shameem Reza
    Shameem RezaJan 6, 2019

    Amazing. 🤓

  • Augustus Yuan
    Augustus YuanJan 7, 2019

    Very cool! Thanks for sharing :)

  • Aldrin Navarro
    Aldrin NavarroJan 10, 2019

    I read a similar article last year which convinced me that Ambient Light Sensor API is very cool! Check it out!

  • M. Andrew Darts
    M. Andrew DartsJan 10, 2019

    So stoked to see someone writing about this!
    The web APIs are growing and I am so ready to see what people build with these!

    Great work!

    • Ananya Neogi
      Ananya NeogiJan 11, 2019

      Thanks! Indeed, web APIs are growing and it's exciting!

  • АнонимJan 17, 2019

    [deleted]

  • Juneau Lim
    Juneau LimJun 16, 2019

    It’s mind-blowing. I never imaged such a thing is possible.
    Furthermore such a small amount of code without asking permission. Love it.
    Thank you so much for letting me know.

  • Rijubrata Bhaumik
    Rijubrata BhaumikJul 12, 2019

    Hello Ananya,
    Great that you liked the ALS feature on Chrome. We are planning to ship ALS on Chrome by default sometime soon. It would be great to get more inputs
    from creative webdev folks. Feel free to ask for more details :)

    Riju,
    (ALS/sensors -chrome+W3C)

  • Gustavo Benedetto Conti Papi
    Gustavo Benedetto Conti PapiDec 15, 2019

    I called you at Codepen.io, but you seem not to read the notification. So I came to alert you that it does not work on Google Chrome on Android phone.

Add comment