Recently the steam has built up to the level where it needs to be set free, so here is my take on the whole HTML5 vs. Flash matter:
HTML5 by itself does not provide scripting or styling
HTML5 is a markup language, markup as in "the collection of tags that describe the specifications of an electronic document, as for formatting", nothing more. To build anything more useful than a bunch of static text and media you will need to rely on...
CSS and Javascript
That's right, RELY being the key word here. You might have heard (or experienced) that CSS and Javascript support across browsers is fragmented and broken due to vendor inability to talk with each other and to find a common understanding when defining web standards.
But how bad is it exactly? How does it look when you put it in perspective with a technology like Flash?
Mouse Events
In Flash Player's Actionscript 3 you have a rich set of mouse events that allow you to distinguish between different states interaction with interface elements. These events allow to create complex user interface elements, nested navigation items, drop-down menus and even multitouch interfaces that work flawlessly. See a full list of supported events here.
In Javascript, you have to check with this compatibility table from QuirksMode.org which looks like a Christmas tree. It's sad but browser vendors have chosen to implement mouse events so differently that most of the time it's impossible to get something to work without using tons of compatibility code and sometimes it's just not possible at all (for example this will never run on Opera).
Consistency
A table of currently supported HTML5 tags can be found here (note the dominating RED color).
Whereas Flash Player 10 supports consistent API through operating systems and devices and is currently deployed on 97% of all internet-enabled computers worldwide (data taken from here)
Clipboard
In Actionscript 3 setting clipboard contents is as easy as calling
Actionscript:
-
System.setClipboard(contents)
In Javascript... well since the native clipboard functionality is only supported in Internet Explorer you will have to EMBED A FLASH FILE and use a js-to-flash bridge to set the clipboard:
JavaScript:
-
function copyIntoClipboard(text) {
-
var flashId = 'flashId-HKxmj5';
-
/* Replace this with your clipboard.swf location */
-
var clipboardSWF = 'http://appengine.bravo9.com/copy-into-clipboard/clipboard.swf';
-
if(!document.getElementById(flashId)) {
-
var div = document.createElement('div');
-
div.id = flashId;
-
document.body.appendChild(div);
-
}
-
document.getElementById(flashId).innerHTML = '';
-
var content = '<embed src="' +
-
clipboardSWF +
-
'" FlashVars="clipboard=' + encodeURIComponent(text) +
-
'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
-
document.getElementById(flashId).innerHTML = content;
-
}
Video
Let me quote diveintohtml5.org for this one: "There is no single combination of containers and codecs that works in all HTML5 browsers. To make your video watchable across all of these devices and platforms, you’re going to have to encode your video more than once."
Hey, thanks but NO THANKS.
I will not go into details on this topic since it was covered many times over before me but currently HTML5 video tag support is fragmented and implementations are slower than Flash due to browser's inability to leverage hardware acceleration. More information here and here. In other words, it's a complete mess.
Styling
So here's a simple example in Actionscript 3, let's draw a semi-transparent box with rounded corners and and rotate it by 7.5 degrees:
Actionscript:
-
with(shape.graphics) {
-
beginFill(0xB4B490,0.6);
-
drawRoundRect(0,0, 100, 100, 12);
-
endFill();
-
}
-
shape.rotation = 7.5;
Makes sense? Sure does.
Now let's take a look at HTML and CSS code required to achieve exactly the same result:
CSS:
-
#box {
-
/* Color and Transparency */
-
background-color: #B4B490;
-
background-color: rgba(180, 180, 144, 0.6); /* FF3+, Saf3+, Opera 10.10+, Chrome */
-
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#99B4B490',EndColorStr='#99B4B490'); /* IE6,IE7 */
-
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#99B4B490',EndColorStr='#99B4B490')"; /* IE8
-
/* Dimensions */
-
width: 100px;
-
height: 100px;
-
-
/* Rounded Corners */
-
-moz-border-radius: 12px; /* FF1+ */
-
-webkit-border-radius: 12px; /* Saf3+, Chrome */
-
border-radius: 12px; /* Opera 10.5, IE 9 */
-
-
/* Rotation */
-
-moz-transform: rotate(7.5deg); /* FF3.5+ */
-
-o-transform: rotate(7.5deg); /* Opera 10.5 */
-
-webkit-transform: rotate(7.5deg); /* Saf3.1+, Chrome */
-
filter: progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=0.9914448613738104, M12=-0.13052619222005157, M21=0.13052619222005157, M22=0.9914448613738104); /* IE6,IE7 */
-
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(SizingMethod='auto expand', M11=0.9914448613738104, M12=-0.13052619222005157, M21=0.13052619222005157, M22=0.9914448613738104)"; /* IE8 */
-
zoom: 1;
-
}
See those values next to filter and -ms-filter? HOW THE HELL should I calculate those matrix values by heart without opening my scientific calculator every time I need to adjust the rotation angle?!
And why do I have to repeat the same statement over and over again for each crappy browser implementation? -moz-o-webkit-ms-gimme-a-break.
And worst of all, why after going through all of this nonsense it still works only on 25% of all browsers?!
[EDIT] By popular demand, here's how it looks in JS + canvas:
HTML:
-
<canvas id="drawing" width="200" height="200">
-
-
</canvas>
JavaScript:
-
var drawingCanvas = document.getElementById('drawing');
-
if(drawingCanvas.getContext) {
-
var width = 100;
-
var height = 100;
-
var radius = 12;
-
var x, y = 0;
-
var ctx = drawingCanvas.getContext('2d');
-
-
ctx.fillStyle = "rgba(180,180,144,0.6)";
-
ctx.beginPath();
-
ctx.moveTo(x,y+radius);
-
ctx.lineTo(x,y+height-radius);
-
ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
-
ctx.lineTo(x+width-radius,y+height);
-
ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
-
ctx.lineTo(x+width,y+radius);
-
ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
-
ctx.lineTo(x+radius,y);
-
ctx.quadraticCurveTo(x,y,x,y+radius);
-
ctx.fill();
-
ctx.rotate(7.5*(Math.PI/180));
-
}
Any better? I thought so... Oh, and if you want this on IE, you have to use a compatibility library.
Licensing
This is a point that gets mentioned over and over again, so let's see:
- Wikipedia states that "On March 14, 2007, WebKit developer Dave Hyatt forwarded an email from Apple's Senior Patent Counsel, Helene Plotka Workman[3], which stated that Apple reserved all intellectual property rights relative to WHATWG’s Web Applications 1.0 Working Draft, dated March 24, 2005, Section 10.1, entitled “Graphics: The bitmap canvas” [4], but left the door open to licensing the patents should the specification be transferred to a standards body with a formal patent policy.". Today, Canvas is still a copyrighted property of Apple Inc.
- HTML, JS and CSS parser implementations of most of the browsers are closed source (with few exceptions).
Now on the opposite side we have this:
Still not convinced?
What Else?
Finally, here's a list of cool functionality that you will miss out on if you choose HTML5, JS and CSS over Flash:
- Sockets
- Video and audio streaming
- Microphone and webcam access
- Embedded fonts (don't get me started)
- Multitouch
- Native 3D transforms
- Graphics shaders and other C++ based extensions (Alchemy)
- DRM
Conclusion
Summing up I would like to say that I like HTML5 *very much* for what it is - a semantic upgrade to HTML4. But please don't call it something like "Flash Player Killer" because doing so simply does not make sense.
Flash is a superior technology allowing for rich and true cross platform experience and it's here to stay for a long long time whether you like it or not.
Flame wars commence... If you have a different point of view or want to add something to the discussion, please leave a comment below. You can also send me a shout at @pauliusuza on twitter.