Home > HTML5 > Using HTML5′s Fullscreen API for Fun and Profit

Using HTML5′s Fullscreen API for Fun and Profit

For the past few weeks I’ve been working on a new super magical awesome feature that involves using the new HTML5 Fullscreen API. As with most brand spankin’ new web APIs, its support and implementation varies per browser. I think it’s worth the effort considering how freaking awesome it is to do fullscreen web apps.

The Basics

OK, let’s get started with the basics of how this new API works. Via the JavaScript function requestFullscreen you tell the browser you want a specific HTML DOM element to fill the entire screen with no browser chrome displayed.

var myNode = document.querySelector("#myFullscreenNode");
myNode.requestFullscreen();

This is not the normal fullscreen mode that many browsers have where the browser’s viewport is simply stretched to the edges of the edges of the screen and the browser chrome is hidden. As far as I know that type of fullscreen mode is not standardized and is not accessible via JavaScript.

Currently Firefox, Safari and Chrome support the fullscreen API. But of course each implements it slightly differently, which is exactly why I’m writing this article and you’re reading it.

Getting started

According to the W3C specification, the first thing you should do is determine if the browser supports the fullscreen API and is currently in a state where it’s safe to go fullscreen. This is achieved via the `fullscreenEnabled` property on the document object. If the property exists and is true this means you can request the browser’s fullscreen mode. (Note the terminology: request. There’s no guarantee it will always work so don’t expect it to.)

You want to use this flag (if available) because a browser may support the fullscreen API but be in a state where it can’t go fullscreen (still loading content, a browser preference pane may be focused, etc).

To determine if fullscreen mode is available, check the .fullscreenEnabled property on the document object like this:

if(document.fullscreenenabled) {
	var myNode = document.querySelector("#myFullscreenNode");
	myNode.requestFullscreen();
} else {
	dont();
}

Currently only Firefox has this property on the document object as ‘mozFullScreenEnabled’ (note the capitalization), so it’s not worth relying on unless you really want to adhere to a draft spec.

The easier way to check if a browser supports the fullscreen API is to create a test HTML Node object and check if it has the requestFullscreen function on it:

var testNode = document.createElement('div');

if(testNode.requestFullscreen) {
	var myNode = document.querySelector("#myFullscreenNode");
	myNode.requestFullscreen();
} else {
	//Fail
}

The above snippet is the spec format, for use in Firefox/Chrome use .mozRequestFullScreen and .webkitRequestFullScreen (again note capitalization!).

Are we there yet?

Let’s assume we have a browser that supports fullscreen mode. We can just call requestFullscreen() on the DOM Node we specify and we’re golden, right? Wrong! Just because we call the function doesn’t mean we’re guaranteed to go fullscreen. The user could press the Escape key during the transition to fullscreen or something could occur in the browser itself where it needs to abort. This is where listening for the events ‘fullscreenchange’ and ‘fullscreenerror’ is helpful (both are available prefixed in Firefox and Chrome, fullscreenerror is not available in Safari).

These events are fired on the document object, not on the node that was requested to go fullscreen. Adding to our code snippet above we get this:

var testNode = document.createElement('div');

if(testNode.requestFullscreen) {
	document.onfullscreenchange = function(event) {
		//Fullscreen mode has changed
	}

	document.onfullscreenerror = function(event) {
		//Error!
	}

	var myNode = document.querySelector("#myFullscreenNode");
	myNode.requestFullscreen();
}

Again, the above code is per the spec, for Firefox and Chrome/Safari use ‘onmozfullscreenchange’ and ‘onwebkitfullscreenchange’, respectively.

Given there’s a fullscreen change event object you’d assume that it will tell you which mode the browser is currently in, right? Wrong! You can’t tell which mode the browser is in from the event fired. Luckily there is a document property to determine which mode the browser is in. (Are we having fun yet?!)

To determine which mode the browser is in check the ‘fullscreenElement’ property of the document object. If this property is not null the browser is in fullscreen mode (and the value is the DOM node that is fullscreen). Firefox, Chrome and Safari all support this property (namespaced).

if(document.fullscreenElement) {
    //Yay, we're fullscreen!
}

Checking for errors

Even if we’ve checked the ‘fullscreenEnabled’ and ‘fullscreenElement’ properties betore we request fullscreenmode, it’s still possible that the browser will deny our request. When this happens the browser will fire a ‘fullscreenerror’ event on the document object.

This can happen if there’s a user preference, security risk or platform limitation regarding fullscreen mode. Fullscreen mode is also only triggerable via user input (click, key press, etc), so if it is requested outside of those events the fullscreenerror event will be fired.

var testNode = document.createElement('div');
if(testNode.requestFullscreen) {
	document.onfullscreenerror = function(event) {
		//Error!
	}
}

Firefox and Chrome support the onfullscreenerror events (prefixed), Safari does not.

All together now

Combining all our code examples above we get the following:

if(document.fullscreenEnabled) {
	document.onfullscreenchange = function(event) {
		if(document.fullscreenElement) {
			//We are fullscreen! Rejoice!
		} else {
			//We're not fullscreen :(
		}
	}

	document.onfullscreenerror = function(event) {
		//Something went wrong...
	}

	var fullscreenNode = document.querySelector("#myFullscreenNode");
	fullscreenNode.requestFullscreen();
}

Unfortunately none of this code will work in any current browsers. A lot of conditional logic is needed to determine which set of fullscreen APIs are available (Firefox, Chrome and Safari all differ).

Fortunately for you, I’ve wrapped it all up into a convenience function that will return the correct set of events and fullscreen function for the browser or false if the current browser does not have fullscreen support:

function FullScreenSupport() {
    var TEST_NODE = document.createElement('div');
        REQUEST_FULLSCREEN_FUNCS = {
            'requestFullscreen': {'change':'onfullscreenchange',
                                  'request':'requestFullscreen',
                                  'error':'onfullscreenerror',
                                  'enabled':'fullscreenEnabled',
                                  'cancel': 'exitFullscreen',
                                  'fullScreenElement':'fullscreenElement'
            },
            'mozRequestFullScreen':{'change':'onmozfullscreenchange',
                                    'request':'mozRequestFullScreen',
                                    'error':'onmozfullscreenerror',
                                    'cancel': 'mozCancelFullScreen',
                                    'enabled':'mozFullScreenEnabled',
                                    'fullScreenElement':'mozFullScreenElement'
            },
            'webkitRequestFullScreen':{'change': 'onwebkitfullscreenchange',
                                       'request': 'webkitRequestFullScreen',
                                       'cancel': 'webkitCancelFullScreen',
                                       'error': 'onwebkitfullscreenerror',
                                       'fullScreenElement': 'webkitCurrentFullScreenElement'
            }
        },

        fullscreen = false;

        for(var prop in REQUEST_FULLSCREEN_FUNCS) {
            if(REQUEST_FULLSCREEN_FUNCS.hasOwnProperty(prop)) {
                if(prop in TEST_NODE) {
                    fullscreen = REQUEST_FULLSCREEN_FUNCS[prop];
                    //Still need to verify all properties are there as
                    //Chrome and Safari have different versions of Webkit
                    for(var item in fullscreen) {
                        if(!(fullscreen[item] in document) &&
                            !(fullscreen[item] in TEST_NODE)) {
                            delete fullscreen[item];
                        }
                    }
                }
            }

            if(fullscreen) {
                break;
            }
        }

        return fullscreen;
}

It ain’t pretty, but it does work. The function will return false if the browser doesn’t support fullscreen mode. Also note that just because a browser supports full screen mode doesn’t mean every function and property related to full screen mode is available, make sure it’s in the object FullScreenSupport returns.

Styling it all

Thought you were done? :)

Along with the long list of JavaScript functions for fullscreen mode, there’s a little bit of CSS styling that is applied to the element that is shown fullscreen. According to the spec, an element that is fullscreen gets this CSS:

  position:fixed;
  top:0; right:0; bottom:0; left:0;
  margin:0;
  box-sizing:border-box;
  width:100%;
  height:100%;
  object-fit:contain;

Firefox applies this by default along with background-color: black, Safari and Chrome do not apply the width and height properties. To make Chrome and Safari match the spec and Firefox’s behavior, you can use the :fullscreen pseudo class to apply these styles:

#myFullscreenNode:-webkit-full-screen { //webkit prefix
  width:100%;
  height:100%;
  background-color: black;
}

Combine that with the FullScreenSupport function and you’ll have a relatively easy to use fullscreen API in three browsers! Also, if you happen to know anyone on the IE team please let them know they should implement it!

References

Categories: HTML5 Tags: , ,
  1. Bungled
    June 15, 2012 at 9:13 am

    “if(!(fullscreen[item] in document) &&”
    should be
    “if(!(fullscreen[item] in document) &&”

    writing a lot of html lately?

    • Bungled
      June 15, 2012 at 9:15 am

      oops, it shows up as & when i typed “(amp&;)”

    • June 15, 2012 at 9:55 am

      Thanks Bungled! WP escaped my code for some weird reason.

  2. Edward
    June 20, 2012 at 1:28 am

    Ah is this why its been broken in Chrome for the past week then?

    • June 20, 2012 at 9:16 am

      Edward: all the functions/properties are there for the latest version of Chrome. You’ll have to be more specific as to what’s broken or not working for you.

  3. Edward
    June 21, 2012 at 12:51 am

    I’m running the latest version of Chrome on 3 different PCs (although they’re all synced to the same account), have attempted disabling a number of extensions but doesn’t seem to make a difference. When I click upload from my homepage, the upload page continuously reloads itself so I can’t upload anything (I have to use the java uploader). If I do it from a gallery, the popup window immediately closes.

    • June 21, 2012 at 10:31 am

      Edward: are you talking about uploading images to SmugMug? If so fill out our help form and we’ll get back to you, thanks! http://help.smugmug.com/customer/portal/emails/new

      We aren’t using the fullscreen api in anything on smugmug.com yet, I’m using it for a to-be-released feature that is unrelated to uploading.

  4. dave eschmeyer
    January 11, 2013 at 6:36 pm

    is there a demo i can download or see?

  5. dave eschmeyer
    January 11, 2013 at 7:00 pm

    a simple code example

  6. dave eschmeyer
    January 11, 2013 at 7:03 pm
  1. June 14, 2012 at 12:08 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: