Getting started with the Ambient Light Sensor

Whether I’m in the car or walking around a new city, Google Maps is one of the apps that I couldn’t live without. It is packed with tons of great features and I find it especially useful when driving in the car. If you've ever used the app and driven at night or under a dark tunnel, the app will adjust the display of the map accordingly and show you a "night" version. This simple change makes it much easier to see depending on the current ambient light.

Ambient Light Sensor - Google Maps night mode

Google Maps on my mobile phone is a native app which has access to various hardware sensors allowing it to determine when to switch to a night display or change the orientation. This got me wondering if it was possible to access these hardware sensors via a web app. As it turns out there is a way! This is where the Ambient Light Sensor comes in.

Ambient Light Sensor

The Ambient Light Sensor API provides developers with the means to determine ambient light levels as detected by the device’s main light detector. This information is available to developers in terms of lux units. If you are building a Progressive Web App and you want to style it differently depending on the light levels in the room, then this could be the feature for you. There are a number of use cases for this feature, such as a web application that provides input for a smart home system to control lighting, a "Kindle" style reading app, or even a web app that calculates settings for a camera with manual controls (aperture, shutter speed, ISO, etc.).

In this article, I will run through a basic example that will show you how to change the styling of the page when a user has low light levels. By the time you are finished reading this example, you should have a good understanding of the Ambient Light Sensor API and how you can start using it in your web applications today.

Getting started

First up, I created a simple web page and named it index.html. The web page doesn’t do a whole lot, but contains a few divs that we will use to display light data on the page.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>title</title>
  </head>
  <body class="brightLight">
    <h1>Ambient Light Sensor</h1>
    <div id="details"></div>  
  </body>
</html>

Next, let’s add some code to our web page to check the current light levels.

<script>
const details = document.getElementById("details");

// Feature detection
if (window.AmbientLightSensor){
    try{
      const sensor = new AmbientLightSensor();
      // Detect changes in the light
      sensor.onreading = () => {
        details.innerHTML = sensor.illuminance;

          // Read the light levels in lux 
          // < 50 is dark room
          if (sensor.illuminance < 50) {
            document.body.className = 'darkLight';
          } else {
            document.body.className = 'brightLight';
          }
      }

      // Has an error occured?
      sensor.onerror = event => document.getElementById("details").innerHTML = event.error.message;
      sensor.start();
    } catch(err) {
      details.innerHTML = err.message;
    }
} else {
  details.innerHTML = 'It looks like your browser doesnt support this feature'; 
}
</script>

Let’s dive into the code above a little further. On line 5, I am checking to see if the current browser supports the Ambient Light Sensor feature. If it does, I am then adding an event listener that will get fired as soon as there are any changes in the light in the room. The great thing about this is that if the user's device doesn't support this feature, it will simply fallback gracefully and they will be none the wiser!

The sensor reads the current light levels in the room in lux units. A lux is equal to one lumen per square metre and is used as a measure of the intensity, as perceived by the human eye. It’s worth noting that the lux levels aren’t precise because the value reported by different devices in the same light can be different, due to differences in the detection method, sensor construction, etc.

In the code above, if the lux levels drop below 50 (equivalent to a dark room), a different CSS style will be applied. Once the levels are light enough, the level will change again. In order to provide visual testing feedback, I’ve also added a div to the page that shows the current value of the lux levels in the room. If you’d like to learn more about common light levels, I recommend reading this article for more details on these values.

That’s it - this feature is now ready to be used.

Show me the money!

Full support is available for this feature in the latest version of Microsoft’s Edge browser, however I have an Android phone and wanted to test this using Chrome browser instead. If you open a new browser tab on your phone and head over to chrome://flags/, scroll till you come across “Generic Sensor Extra Classes” and enable this flag. Now that this has been enabled, your browser will be able to read the ambient light using it’s built in sensor.

If you’d like to try this for yourself, you can head over to the following URL on Github. Remember that you will need to visit this URL with a device that has a camera and a browser that supports these features.

Here is a little video of this web page in action - apologies that it is a little blurry.

At the time of writing this article, browser support is limited - If you’d like to see more details, please see the chart below.

Can I Use ambient-light? Data on support for the ambient-light feature across the major browsers from caniuse.com.

The source code for this example is available on Github at the following URL. I hope you enjoy!