Creating Well-Behaved Sites With The Page Visibility API

About The Author

Dudley Storey has been making web pages for almost has long as there has been a web to create them on. A writer, designer and teacher of web development and 3D, … More about Dudley ↬

Email Newsletter

Weekly tips on front-end & UX.
Trusted by 200,000+ folks.

As developers and designers it’s our job to make the web welcoming, not overwhelming. The HTML5 Page Visibility API is used effectively in recent projects by Active Theory, such as their work for Under Armor and A Spacecraft For All: click to another tab and you’ll find that the multimedia presentation pauses and the music fades away. This behavior typifies what I like to call the “polite web”: sites that are considerate of users’ attention, bandwidth and abilities.

We’re all resigned to it: launching a browser reloads every tab you previously had open, blasting a cacophonous mix of sound and video. While browsers have made it easier to control this experience with tab icons and extensions like MuteTab, for most people this behavior presents a confusing and disorienting experience. As developers and designers it’s our job to make the web welcoming, not overwhelming.

Doesn’t it make sense that sites should only be active when they are the primary focused tab? Why are we burning up batteries and processor cycles with animation that can’t be seen?

Thankfully, there is a solution: the HTML5 Page Visibility API. You can see it used particularly effectively in recent projects by Active Theory, such as their work for Under Armor and A Spacecraft For All: click to another tab and you’ll find that the multimedia presentation pauses and the music fades away. This behavior typifies what I like to call the “polite web”: sites that are considerate of users’ attention, bandwidth and abilities.

In the past developers have tried to create this behavior by adding onblur() and onfocus() window handlers. While they are considerably better than nothing, the approach is limited by the fact that it can’t tell if the window is actually hidden to the user. For example, having two browser windows side-by-side and switching between them would still register as onblur() or onfocus(), even though the content in each remains perfectly visible.

Implementing Page Visibility

While there are many possibilities for using the Page Visibility API, perhaps the most obvious use case is when a page contains video: there’s usually little point in continuing to play video content if the user can’t see it.


<video autoplay controls id="videoElement">
    <source src="rar.mp4">
    <source src="rar.webm">
</video>

<script>
var videoElement = document.getElementById("videoElement");
document.addEventListener("visibilitychange", function() {
if (document.hidden) {     
videoElement.pause();  
} else {
videoElement.play();   
} 
});
</script>

The one problem with this is that it’s a little abrupt: the audio on the video starts and stops as if cut off with a guillotine when the user switches tabs. The presentation could be improved significantly by fading the audio in and out as the tab is focused. If we’re using jQuery, we can employ a neat use of the animate method to do so.

<script>
var videoElement = document.getElementById("videoElement");

document.addEventListener("visibilitychange", function() {
if (document.hidden) {     
$("#videoElement").animate({volume: 0}, 1000, "linear", function() {
videoElement.pause();
});
} else {
videoElement.play();  
$("#videoElement").animate({volume: 1}, 1000, "linear");
} 
});
</script>

The Spec

The Page Visibility API spec is surprisingly simple, consisting of just two methods: document.hidden returns true or false depending on the status of the browser window; and those same states are reflected in string form for document.visibilityState (hidden and visible, respectively, with two optional values of prerender and unloaded), with visibilitychange available as an event. document.visibilityState can be useful in determining why a document is not visible, but otherwise document.hidden covers most needs.

Precautionary Principles And Browser Support

The Page Visibility API takes a deliberately conservative approach to reporting a hidden document: your page will be reported as hidden if the user switches to another tab in the same browser window, but not if you move another window to obscure your page. The API is not foolproof, and will return false positives in some circumstances, erring on the side of caution.

Support for the Page Visibility API is excellent: all modern browsers, with the exception of Opera Mini, fully support the API, including IE10+. Vendor prefixes are also refreshingly absent from implementation of the spec: the only browsers that currently need a –webkit prefix are Android and Blackberry. For that reason (and for the sake of simplified illustration) I have not included any prefixes in the code samples above, although they are easy enough to include and test for.

The Page Visibility API is also an excellent example of progressive enhancement. If the browser doesn’t support the API, the script will be ignored, and the user will simply be subjected to the usual uncontrolled cacophony.

Other Uses

While audio and video content are obvious candidates for using the Page Visibility API, there are many other possibilities: pausing a slider or presentation while the site remains out of focus, or changing the visual state of the page as it remains neglected.

Considerate use of the API can help make the web a better, greener, and more responsible place, and I would strongly encourage developers to consider how to integrate it into their projects.

Further Reading

Smashing Editorial (il, og, ml, mrn)