Adding Fullscreen to WebApps using the JavaScript API

In addition to the standard (F11) full screen modes in web browsers, there is now also a way to enable full screen using JavaScript, providing fullscreen functionality from within web apps.

Browser Support

  • IE11 onwards
  • Firefox 10 onwards
  • Chrome 15 onwards
  • Safari 5.1 onwards
  • Opera 12.1 onwards

Source: caniuse.com/fullscreen

The FullScreen API

Here is a list of the members of the Fullscreen API. I will show examples of how to use the members in further detail below.

MemberTypeDescription
element . requestFullscreen()MethodDisplays the element fullscreen.
document . exitFullscreen()MethodStops any element within document from being displayed fullscreen.
document . fullscreenElementPropertyReturns the element that is displayed fullscreen, or null if there is no such element.
document . fullscreenEnabledPropertyReturns true if document has the ability to display elements fullscreen, or false otherwise.
fullscreenchangeEventEvent fired when an element is displayed fullscreen, or when it exists fullscreen.
fullscreenerrorEventEvent fired when fullscreen display is requested of an element, but the request is not successful.
:fullscreenPseudo classAllows you to specify CSS properties to be used when an element is in fullscreen mode.
::backdropPseudo elementAllows you to specify background CSS properties when an element is displayed in fullscreen mode.
allowfullscreenAttributeMust be specified as an attribute of an iframe to allow elements within the iframe to be displayed fullscreen.

Source: w3.org/TR/fullscreen/

Cross Compatibility

Because the W3C specification for fullscreen is not yet final, currently all of the main browsers are using vendor prefixing. This complicates the issue as it means that for each feature, you need to use the standard variant as well as the 3 browser specific variants in order to ensure cross compatibility.

It is good practice to use the non-prefixed version first as it will improve performance in the future when browsers no longer use the prefixed variants.

Something that is slightly difficult to spot, but could cause an issue if you are not careful is that in moz-prefixed variants, the S in fullscreen is capitalised, however in all other variants it in in lower case. For example, element.mozRequestFullScreen() vs element.webkitRequestFullscreen().

Checking Availability

Checking the availability of fullscreen is a very important feature as it allows you to specify different behavior for fullscreen controls for example when the content is being accessed from an older browser without support for the fullscreen API, or when the content is contained within an element that doesn’t allow fullscreen, for example an iframe without the allowfullscreen attribute set.

The following code provides a boolean fullscreenEnabled that will be true if elements within the document can be fullscreen, and false if not:

    var fullscreenEnabled = document.fullscreenEnabled ||
            document.msFullscreenEnabled ||
            document.mozFullScreenEnabled ||
            document.webkitFullscreenEnabled;

Entering Fullscreen

Due to vendor prefixing, there are two parts to entering fullscreen. Firstly, you must find out which vendor prefix you need to use, and from there you can request fullscreen on an element.

Here is some example code showing this:

    function makeFullscreen(element) {
        if (element.requestFullscreen) {
            element.requestFullscreen();
        } else if (element.msRequestFullscreen) {
            element.msRequestFullscreen();
        }else if (element.mozRequestFullScreen) {
            element.mozRequestFullScreen();
        }else if (element.webkitRequestFullscreen) {
            element.webkitRequestFullscreen();
        }
    }

Exiting Fullscreen

As with entering fullscreen, to exit fullscreen we must first find out the vendor prefix to use before cancelling fullscreen on the document.

Here is some example code showing this:

    function cancelFullscreen() {
        if (document.exitFullscreen) {
            document.exitFullscreen();
        } else if (document.msExitFullscreen) {
            document.msExitFullscreen();
        }else if (document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
        }else if (document.webkitCancelFullScreen) {
            document.webkitCancelFullScreen();
        }
    }

Checking if there exists a Fullscreen Element

It is also possible to find out if there is currently an element fullscreen. This could be useful, for example if you would like a single function to toggle fullscreen.

The following code provides a boolean fullscreenElement that will be true if an element is currently fullscreen within the document, and false if not:

    var fullscreenElement = !(!document.fullscreenElement &&
        !document.msFullscreenElement &&
        !document.mozFullScreenElement &&
        !document.webkitFullscreenElement);

And here is an example function that will toggle fullscreen on the document body:

function toggleFullScreen() {
    if (!document.fullscreenElement && !document.msFullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement) {
        if (document.body.requestFullscreen) {
            document.body.requestFullscreen();
        } else if (document.body.msRequestFullscreen) {
            document.body.msRequestFullscreen();
        }else if (document.body.mozRequestFullScreen) {
            document.body.mozRequestFullScreen();
        }else if (document.body.webkitRequestFullscreen) {
            document.body.webkitRequestFullscreen();
        }
    } else {
        if (document.exitFullscreen) {
            document.exitFullscreen();
        } else if (document.msExitFullscreen) {
            document.msExitFullscreen();
        }else if (document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
        }else if (document.webkitCancelFullScreen) {
            document.webkitCancelFullScreen();
        }
    }
}

Using the Fullscreen Events

There are two events that you can add listeners to in the Fullscreen API: fullscreenerror and fullscreenchange. These events also have vendor prefixes.

The fullscreenerror event fires when attempting to go fullscreen and not being able to, for example when the element is within an iframe that doesn’t have the allowfullscreen attribute set. This fullscreenerror event does not fire if the user refuses the request to go full screen. In that case, you will receive two fullscreenchange events.

The fullscreenchange event is very self explanatory, it fires whenever the fullscreen state changes.

Here is an example showing all of the vendor-prefixed event names:

    //No prefix
    document.addEventListener("fullscreenerror", function (evt) {
        console.error("full screen error has occurred " + evt.target);
    }, false);
    document.addEventListener("fullscreenchange", function (evt) {
        console.error("full screen change has occured " + evt.target);
    }, false);
 
    //MS prefix
    document.addEventListener("MSFullscreenError", function (evt) {
        console.error("full screen error has occurred " + evt.target);
    }, false);
    document.addEventListener("MSFullscreenChange", function (evt) {
        console.error("full screen change has occured " + evt.target);
    }, false);
 
    //moz prefix
    document.addEventListener("mozfullscreenerror", function (evt) {
        console.error("full screen error has occurred " + evt.target);
    }, false);
    document.addEventListener("mozfullscreenchange", function (evt) {
        console.error("full screen change has occured " + evt.target);
    }, false);
 
    //webkit prefix
    document.addEventListener("webkitfullscreenerror", function (evt) {
        console.error("full screen error has occurred " + evt.target);
    }, false);
    document.addEventListener("webkitfullscreenchange", function (evt) {
        console.error("full screen change has occured " + evt.target);
    }, false);

An example of using the fullscreenchange event is to place specific behavior on elements based on whether the document is currently fullscreen, for example showing an ‘End Fullscreen’ button when fullscreen, and a ‘Start Fullscreen’ button when not.

You might like to log an error using the fullscreenerror event, however if you are using the example code above to disable fullscreen options when fullscreen is unavailable, it is unlikely that you should need to use this event.

Using the Fullscreen CSS

The least standard behavior in the different browser implementations of the Fullscreen API is how they are styled when in fullscreeen. There were two specific changes that I had to make for each browser to appear the same.

The first is that when I set the body fullscreen, IE11 styles the background black, requiring the background set on the ::backdrop pseudo element.

body::-ms-backdrop {
    background: /*background setting*/;
}

The other required change is for Chrome. When setting the body to fullscreen, Chrome likes to display a black background and start display 50% down the page:

chromestrange

To fix this, it requires using the :full-screen pseudo class, like so:

body:-webkit-full-screen {
    width: 100%;
    height: 100%;
}

The vendor prefixes for :fullscreen are: :-ms-full-screen and :-webkit-full-screen. The vendor prefixes for ::backdrop are: ::-ms-backdrop and ::-webkit-backdrop. It appears that Firefox does not yet support these features.

Important: It is not possible to combine multiple prefixed versions in the same CSS block. You must use one CSS block for each prefix and duplicate the styles.

/*Does not work*/
#element:-webkit-full-screen, #element:-ms-fullscreen {
    /*styles*/
}
/*Use the following:*/
#elemement:-webkit-full-screen {
    /*styles*/
}
#elemement:-ms-fullscreen {
    /*styles*/
}

The allowfullscreen Attribute

A frequently asked question with the Fullscreen API is how to make the fullscreen mode functional when the content is within an iframe. The simple answer sis that the iframe must contain the allowfullscreen attribute. There are vendor-prefixes, however in my experience they are no longer necessary.

<iframe src="iframesrc" allowfullscreen>

API Suggestion

One of my disappointments with the JavaScript API for fullscreen is that it’s not possible to make the fullscreen state persist between web pages (F11 allows this). It makes perfect sense to disallow this across different domains, but it makes for a poor experience when browsing around the same web app.

Another security feature is that the fullscreen request must be tied with a user event, meaning it’s not possible to go fullscreen onload, but it is allowed with an onclick event. This means it’s not possible for us to pass some state between pages to maintain fullscreen with a call within  onload, so there really is no way around this – aside from Ajax loading the next page in.

The Fullscreen API in Action

You can see the API in action within the viewer for our PDF to HTML5 converter. You can try the PDF to HTML5 converter online, or play with the viewer using already converted example files.

This article is part of a series of articles with suggestions for enhancing your HTML5 content. You can also read about Adding Annotations with Annotator.js, Optimising Images using PNGQuant, Password Protecting content with Apache htaccess, and Measuring Content Performance with Google Analytics.

If you’re a first-time reader, or simply want to be notified when we post new articles and updates, you can keep up to date by social media (TwitterFacebook and Google+) or the Blog RSS.

Related Posts:

The following two tabs change content below.
Leon is a developer at IDRsolutions and product manager for JPDF2HTML5. He is responsible for managing the JPDF2HTML5 product strategy and roadmap, and also spends a lot of his time writing code to build new features, improve functionality, fix bugs, and improve the testing for JPDF2HTML5.
Leon Atherton

About Leon Atherton

Leon is a developer at IDRsolutions and product manager for JPDF2HTML5. He is responsible for managing the JPDF2HTML5 product strategy and roadmap, and also spends a lot of his time writing code to build new features, improve functionality, fix bugs, and improve the testing for JPDF2HTML5.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>