html5 features detection
Article, HTML5

HTML5: features detection

As I said in my previous article about the quick introduction to HTML5, you have to think of HTML5 as a collection of new APIs and not as a one single big API. And for that reason, you can’t say I want to « detect HTML5 » in my application, because it just does not make any sense!

As a matter of fact, you can detect the new features of HTML5: the geolocation API, the localStorage API, the canvas element … And in order to do so, let me first explain to you (rapidly) how browser work.

NOTE: in this article, we are only going to see how to detect some of the HTML5 features! If you want to know how to use these features, please see the related articles.
When the browser renders a web page, it constructs an object for each HTML element it found in the page, so each <p>, <div>, <h1> tags is represented as a unique object. This collection of objects is well known as the DOM, or the Document Object Model.
Besides, each object in the DOM has its own properties, but may also have some properties in common with other objects. The DOM also contains some objects such as the window object or the document object, that are not related to other objects.

So, you may be wondering why am I telling you that, well simply because most of the detection techniques of HTML5 features deal with the DOM objects and their attributes. How? Actually, some if not most of the new HTML5 elements have unique attributes, and using that information, we will be able to know if a browser has this specific feature built in or not.

Well, let’s begin :)

There are four basic techniques for detecting whether a browser supports a particular feature. From simplest to most complex:

  1. Check if a certain property exists on a global object (such as window or navigator).
  2. Create an element, then check if a certain property exists on that element.
  3. Create an element, check if a certain method exists on that element, then call the method and check the value it returns.
  4. Create an element, set a property to a certain value, then check if the property has retained its value.

1 Canvas

The MDN guys define the canvas element as the following:

<canvas> is a new HTML element which can be used to draw graphics using scripting (usually JavaScript). It can for instance be used to draw graphs, make photo compositions or do simple (and not so simple) animations.

So, in other words, HTML5 defines a set of functions (“the canvas API”) for drawing shapes, defining paths, creating gradients, applying transformations and even .

The canvas detection uses the technique #2. In fact, browsers that support this element will create a canvas object with a getContext() method. This is a basic example on how to use this technique:


function detect_canvas() {
  return !!document.createElement('canvas').getContext;
}

This function creates a empty canvas object which will not be attached to your document! And after creating this object, we will check if it has the getContext() method. If the brwoser supports the canvas API, this method will be available. Then, we will use the double-negative trick !! to force the result to a boolean value.

2 Video

Modern browsers that support HTML5 are now able to play videos thanks to the new video element.So no more plugins! Plus, this new element was initially designed to be simply and completely ignored by older browsers, but you can use this to your advantage and tell the browser to use a plugin to play your video.

However, because there are many video formats and each browser constructor want to use its own video format in its browser, you will have to provide different file format of your videos if you want it to be viewed correctly! The video format that are not supported by a browser will be ignored.

If somehow you still want to detect to video API, you will have to use the technique #2 like we did for the canvas element.


function supports_video() {
  return !!document.createElement('video').canPlayType;
}

Please note that if the browser supports the video API, it will create a video object with a unique canPlayType() method.

3 Video Format

Now, in order to check for video format, we will use the technique #3 as the following:


function detect_ogg_theora_codec() {
  if (!supports_video()) { return false; }
  var vid = document.createElement("video");
  return vid.canPlayType('video/ogg; codecs="theora, vorbis"');
}

What this function does is it starts by checking for video support, if the browser does support the video API, we will then create a video object, and assign a reference vid to it. Next, we use the canPlayType() method to ask the browser if it can play a certain video format, or codec. Here, we are asking for OGG Theora codecs, for this we use a technical string value video/ogg; codecs=”theora, vorbis. If we wanted to check for Google WebM codec, we would have used video/webm; codecs=”vp8, vorbis”, and video/mp4; codecs=”avc1.42E01E, mp4a.40.2″ for the H.264 format.

Please note that the canPlayType() method does not return a boolean value, but a string:

  1. “probably” if the browser is quit sure it can play this format
  2. “maybe” if the browser thinks it might be able to play this format
  3. “” (an empty string) if the browser is certain it can’t play this format

For more information about vide format, I recommend you to read this little introduction to video format.

4 Local Storage

The Local Storage is a new API in HTML5 that allow a web application to store data on the client computer, like Cookies. But think of it as the a replacement for Cookies though, and in addition the Local Storage lets you store up to 5MB per domain in Mozilla Firefox, Google Chrome, and Opera, and 10MB per storage area in Internet Explorer, and the data is hosted on the client computer, whereas Cookies are limited in size and require extra requests between the client and the server, which of course take time and bandwidth.

The Local Storage feature can be detected using the technique #1. If the browser supports the Local Sotrage API, it will create a localstorage property in the global object window.


function supports_local_storage() {
  try {
    return 'localStorage' in window && window['localStorage'] !== null;
  } catch(e){
    return false;
  }
}

As you may notice, we’ve wrapped the feature detection in a try … catch … statement, to avoid errors that may be raised by certain browsers!

5 Web Workers

With Web Workers you will be able to execute JavaScript in the background. In fact, some JavaScript tasks as  complex mathematical calculations, or accessing the local database, even making server requests can considerably slow the UI, if not freeze it completely!

So, Web Workers were designed to run this kind of tasks in the background, or if you will, in an other thread, so the main thread can still handle the UI scrolling, clicking … and all the user events.

Detecting this API uses the technique #1 like this:


function supports_web_workers() {
  return !!window.Worker;
}

So, as you notice, the idea behind this technique is looking for the property Worker inside the global object window.

6 Offline Web Applications

When you visit a web site, the browser caches static pages and files for later use (if unchanged of course). So even you’re offline (not connected to the Internet) you will still be able to read these static files. However, what about web application? Things such as Google Gmail or Google Documents.

HTML5 has got the answer: Offlline Web Application API ! The main purpose of this API is to allow you to define all the necessary files that your application needs to work offline. These files can be HTML, images, CSS, JS and even videos!

To detect this feature, you need to use the technique #1 and detect the applicationCache property:


function supports_offline() {
  return !!window.applicationCache;
}

Right?

7 Geolocation

This API is self explanatory! It lets you discover where you are on this planet :)
In order to locate your position, this API uses either your IP address, your wireless connection network, the cell tower your phone is connected to or the GPS information.

To detect this API, use the technique #1, because if the browser supports it, it creates a geolocation property inside the navigator global object:


function supports_geolocation() {
return !!navigator.geolocation;
}

NOTE: if a web application is set to use this API, the browser will ask your permission in order to activate the Geolocation feature!

8 Input Types

You are certainly familiar with classic web forms, that define input text fields, password fields, check boxes … But did you know that HTML5 offers a huge list of new cool web forms fields:

  1. <input type=”search” /> for search fields (see note below),
  2. <input type=”number” /> for numbers,
  3. <input type=”range” /> for sliders,
  4. <input type=”color” /> for color pickers,
  5. <input type=”tel” /> for telephone numbers,
  6. <input type=”url” /> for web addresses,
  7. <input type=”email” /> for email addresses,
  8. <input type=”date” /> for calendar date pickers,
  9. <input type=”month” /> for months,
  10. <input type=”week” /> for weeks,
  11. <input type=”time” /> for timestamps,
  12. <input type=”datetime” /> for precise, absolute date+time stamps,
  13. <input type=”datetime-local” /> for local dates and times.

NOTE: The W3C guys explain the main difference between text fields and search fields as:

« The difference between the Text state and the Search state is primarily stylistic: on platforms where search fields are distinguished from regular text fields, the Search state might result in an appearance consistent with the platform’s search fields rather than appearing like a regular text field. »

So, these fields are straightforward to understand and in order to figure out if your browser supports them, and which ones, you will use the technique #4.


function supports_new_inputs(){
    var inp = document.createElement("input");
    inp.setAttribute("type", "time");
    return inp.type !== "text";
}

Well, in the code above, we define a method that creates an dummy input object in the memory. And please note that the default type of input fields is “text”! Then, we set the type attribute on this dummy field to the input type you want to detect, here we used time. So, if the browser does not support the type we are trying to detect, it will simply ignore the inp.setAttribute(“type”, “time”); instruction, and the type attribute will retain the default value which is “text”.

If you are not familiar with the !== operator, just keep in mind that it checks both values and types!

Now, you will have to upgrade the method above in order to check all the input elements  :)

So, here we saw some common techniques on how to detect some of the new API of HTML5 and if you want to know more about HTML5, I advice you to read the official W3C draft about HTML5.

Standard