Battery Status API experiment

Screenshot of JavaScript battery API experiment
Battery UI element

The JavaScript Battery Status API offers some interesting additional functionality that we can leverage for UI elements. Browser support is getting better—at the time of writing (Feb, 2017), Chrome, FireFox and Opera are good to go, but leaves glaring omissions of Safari/iOS.

This little experiment creates a simple battery UI element, with its background an indicator of battery percentage remaining (plus percentage text): CodePen Experiment

The API provides a bunch of events we can hook into:

  • chargingchange – is the battery charging?
  • levelchangepercentage of battery remaining
  • chargingtimechangeamount of time until battery is charged (estimate)
  • dischargingtimechangeamount of time until batter is discharged (estimate)

All we need to do is check that we have support for the API and off we go:

navigator.getBattery().then(function(battery) { ... });

Once we know we have battery API support, we can go ahead and add some listeners for the new events and update our UI as we need. Note, we don’t use any libraries here, this is raw JavaScript:

const $batteryPercentage = document.querySelector(".js-guage");
const $batteryPercentageDisplay = document.querySelector(".js-percentDisplay");
const $batteryStatusDisplay = document.querySelector(".js-statusDisplay");

navigator.getBattery().then(function(battery) {
 
 function initBattery(){
   updateChargeInfo();
   updateLevelInfo();
 }
 
 battery.addEventListener('chargingchange', function(){
   updateChargeInfo();
 });
 
 battery.addEventListener('levelchange', function(){
   updateLevelInfo();
 });
 
 function updateChargeInfo(){
   let _batteryChargeStatus = battery.charging ? "Battery Charging" : "Battery Draining"; 
   $batteryStatusDisplay.innerHTML = _batteryChargeStatus;
 }

 function updateLevelInfo(){
   let _batteryLevel = Math.round(battery.level * 100) + "%";
   $batteryPercentage.style.width = _batteryLevel;
   $batteryPercentageDisplay.innerHTML = _batteryLevel;
 }
 
 initBattery();

});

What could we use the Battery Status API for?

  • Intensive or full-screen scripts could warn the user if the battery was low before beginning, such as Canvas, WebGL or media handling.
  • Coupled with up-coming CSS selector prefers-reduced-motion we could trigger low-animation CSS when the battery is getting tight.

Details of support for the Battery Status API can be found on Can I Use.

Visible password toggle with CSS and JS

Password fields usually mask their content, but is that really good UX?

UX challenges of password fields

  • User ‘loses their place’ forcing them to start entering the password again.
  • Password hard to type or complex, no visual guide to text being entered.
  • Difficulty in paste a password from elsewhere.
  • Difficult to visually check validity of password before submitting.
  • Hard to copy password elsewhere before submitting.

Technical solution

An increasingly common pattern is to allow the user to toggle the visibility of the password field content, which has a number of accessibility benefits.

Screenshot of form with regular password field
Regular password field.

Following progressive enhancement we can do this simply in JavaScript, however there are a few things to consider:

 

  1. Many users have password manager add-ons—such as LastPass—which may adapt the display of password fields, so we have to be careful when it comes to styling the field itself.
  2. Changing the field <input type="password" ...> to text in JavaScript is simple enough, but it may confuse password managers (even those built into a browser) and irritate users (because their password manager is now broken…).
  3. There’s a possibility that the browser could cache or save the state of the field in plain text, which would be a Bad Thing.
Screenshot of password field with its content being displayed.
Password field with content revealed.

Taking point 2, we can be a little smarter about how we handle form submits and ensure we only ever submit password fields, regardless of a toggled display state. This prevents point 3.

By placing the toggle outside of the password field, we can avoid most visual clashes with add-ons or password managers, covering point 1.

The are downsides to this solution: The user has to have JavaScript enable for start, which you cannot guarantee (but thanks to progressive enhancement, the form will still work). Secondly, it’s still possible for password managers to do strange things to the form fields which cannot be accounted for.

A CodePen demonstrating this technique can be found here.

Responsive modal dialogs

Screenshot of modal dialog masking content
Modal window with full-viewport mask

A super simple responsive modal window with minimal JavaScript.

  • Mobile friendly (mobile first, natch!), fills the viewport on mobiles
  • Keyboard navigable
  • Marked up for accessibility
  • Masks the content on desktop

Particular attention here on the accessible aspects of modal markup: aria-labeledby, aria-describedby and the toggling of aria-hidden on show/hide.

Basic modal markup with these aria properties:

<div class="modal"
 data-modal="dialog1"
 role="dialog" 
 aria-labelledby="modal-label"
 aria-describedby="modal-description"
 aria-hidden="false">

Then matching elements inside the modal itself:

<h2 id="modal-label">
 My modal title
</h2>
...
<p id="modal-description">Modal description</p>
Screenshot of modal dialog filling viewport
Fills viewport on smaller devices

A demo can be found on CodePen.