The standard way to deal with situations where the browser does not support the HTML5 <canvas>
tag is to embed some fallback content like:
<canvas>Your browser doesn't support "canvas".</canvas>
But the rest of the page remains the same, which may be inappropriate or misleading. I'd like some way of detecting canvas non-support so that I can present the rest of my page accordingly. What would you recommend?
There are two popular methods of detecting canvas support in browsers:
Matt's suggestion of checking for the existence of
getContext
, also used in a similar fashion by the Modernizr library:Checking the existence of the
HTMLCanvasElement
interface, as defined by the WebIDL and HTML specifications. This approach was also recommended in a blog post from the IE 9 team.My recommendation is a variation of the latter (see Additional Notes), for several reasons:
getContext
approach is significantly slower across all browsers, because it involves creating an HTML element. This is not ideal when you need to squeeze as much performance as possible (in a library like Modernizr, for example).There are no noticeable benefits to using the first method. Both approaches can be spoofed, but this not likely to happen by accident.
Additional Notes
It may still be necessary to check that a 2D context can be retrieved. Reportedly, some mobile browsers can return true for both above checks, but return
null
for.getContext('2d')
. This is why Modernizr also checks the result of.getContext('2d')
. However, WebIDL & HTML ― again ― gives us another better, faster option:Notice that we can skip checking for the canvas element entirely and go straight to checking for 2D rendering support. The
CanvasRenderingContext2D
interface is also part of the HTML specification.You must use the
getContext
approach for detecting WebGL support because, even though the browser may support theWebGLRenderingContext
,getContext()
may return null if the browser is unable to interface with the GPU due to driver issues and there is no software implementation. In this case, checking for the interface first allows you to skip checking forgetContext
:Performance Comparison
Performance of the
getContext
approach is 85-90% slower in Firefox 11 and Opera 11 and about 55% slower in Chromium 18.