Scalability, Limitations, and Effects

Matt Fisher

August 2013

(For more resources related to this topic, see here.)

HTML5 limitations

If you haven't noticed by now, many of the HTML5 features you will use either have failsafes, multiple versions, or special syntax to enable your code to cover the entire spectrum of browsers and supported HTML5 feature sets within them. As time passes and standards become solidified, one can assume that many of these failsafes and other content display measures will mature into a single standard that all browsers will share. However, in reality this process may take a while and even at its best, developers may still have to utilize many of these failsafe features indefinitely. Therefore, a solid understanding of when, where, and why to use these failsafe measures will enable you develop your HTML5 web pages in a way that can be viewed as intended on all modern browsers.

To aid developers in overcoming these previously stated issues, many frameworks and external scripts have been created and open sourced, allowing for a more universal development environment saving developers countless hours when starting each new project. Modernizr ( has quickly become a must-have addition for many HTML5 developers as it contains many of the conditions and verifications needed to allow developers to write less code and cover more browsers. Modernizr does all this by checking for a large majority (more then 40) of the new features available in HTML5 in the clients browser and reporting back if they are available or not in a matter of milliseconds. This will allow you as the developer to determine if you should display an alternate version of your content or a warning to the user.

Getting your web content to display properly in all browsers is and always has been the biggest challenge for any web developer and when it comes to creating cutting edge interesting content, the challenge usually becomes harder. To allow you to better understand how these features look without the use of third-party integration, we will avoid using external libraries for the time being. It is worth noting how each of these features and others look in all browsers. Therefore make sure to test the examples as well as your own work in not just your favorite browser, but many of the other popular choices as well.

Object manipulation with CSS3

Prior to the advent of CSS3, web developers used a laundry list of content manipulation, asset preparation, and asset presentation techniques in order to get their web page layout the way they wanted in every browser. Most of these techniques would be considered "hacks" as they would pretty much be a work around to enable the browser to do something it normally wouldn't. Features such as rounded corners, drop shadows, and transforms were all absent from a web developer's arsenal and the process of getting things the way you want could get mind numbing. Understandably, the excitement level surrounding CSS3 for all web developers is very high as it enables developers to perform more content manipulation techniques then ever before without the need for prior preparation or special browser hacks. Although the list of available properties in CSS3 is massive, let's cover some of the newest and most exciting of the lot.


It's true that some designers and developers say drop shadows are a part of the past, but the usage of shadowing HTML elements is still a popular design choice for many. In the past, web developers needed to perform tricks such as stretching small gradient images or creating the shadow directly into their background image to achieve this effect in their HTML documents. CSS3 has solved this issue by creating the box-shadow property to allow for drop shadow like effects on your HTML elements.

To remind us how this effect was accomplished in ActionScript 3, let's review this code snippet:

var dropShadow:DropShadowFilter = new DropShadowFilter();
dropShadow.distance = 0;
dropShadow.angle = 45;
dropShadow.color = 0x333333;
dropShadow.alpha = 1;
dropShadow.blurX = 10;
dropShadow.blurY = 10;
dropShadow.strength = 1;
dropShadow.quality = 15;
dropShadow.inner = false;
var mySprite:Sprite = new Sprite();
mySprite.filters = new Array(dropShadow);

As mentioned before, the new box-shadow property in CSS3 allows you to append these shadowing effects with relative ease and many of the same configuration properties:

.box-shadow-example {
box-shadow: 3px 3px 5px 6px #000000;

Despite the lack of property names on each of the values applied to this style, you can see that many of the value types coincide with what was appended to the drop shadow we created in ActionScript 3.

This box-shadow property is assigned to the .box-shadow-example class and therefore will be applied to any element that has that classname appended to it. By creating a div element with the box-shadow-example class, we can alter our content to look something like the following:

<div class="box-shadow-example">CSS3 box-shadow Property</div>

As straightforward as this CSS property is to add to your project, it declares a lot of values all in a single line. Let's review each of these values in order that we can understand them better for future usage. To simplify the identification of each of the variables in the property, each of these have been updated to be different:

box-shadow: 1px 2px 3px 4px #000000;

These variables are explained as follows:

  • The initial value (1px) is the shadow's horizontal offset or if the shadow is going to the left or to the right. A positive value would place the shadow on the right of the element, a negative offset will put the shadow on the left.
  • The second value (2px) is the vertical offset, and just like the horizontal offset value, a negative number would generate a shadow going up and a positive value would generate the shadow going down.
  • The third value (3px) is the blur radius that controls how much blur effect will be added to the shadow. Declaring a value, for example, 0 would create no blur and display a very sharp looking shadow. Negative values placed into the blur radius will be ignored and render no different then using 0.
  • The fourth value (4px) and last of the numerical properties is the spread radius. The spread radius controls how far the drop shadow blur will spread past the initial shadow size declaration. If a value 0 is used, the shadow will display with the default blur radius set and apply no changes. Positive numerical values will yield a shadow that blurs further and negative value will make the shadow blur smaller.
  • The final value is the hexadecimal color value, which states the color that the shadow will be in.

Alternatively, you could use box-shadow to apply the shadow effect to the interior of your element rather then the exterior. With ActionScript 3, this was accomplished by appending dropShadow.inner = true; to the list of parameters in your DropShadowFiler object. The CSS3 syntax to apply box-shadow properties in this manner is very similar as all that is required is the addition of the inset keyword. Consider the following code snippet, for example:

.box-shadow-example {
box-shadow: 3px 3px 5px 6px #666666 inset;

This would produce a shadow that would look like the following screenshot:


Just like the box-shadow property, text-shadow lives up to its name by creating the same drop-shadowing effect, specifically for text:

text-shadow: 2px 2px 6px #ff0000;

Like box-shadow, the initial two values for text-shadow are the horizontal and vertical offsets for the shadow placement. The third value, which is optional is the blur size and the fourth value is the hexadecimal color:


Just like element or text shadowing, adding rounded corners to your elements prior to CSS3 was a chore. Developers would usually append separate images or use other object manipulation techniques to achieve this effect on the typically square or rectangle shaped elements. With the addition of the border-radius setting in CSS3, developers can easily and dynamically set element corner roundness with only a couple of line of CSS all without the usage of vector 9 slicing like in Flash.

Since HTML elements have four corners, when appending the border-radius styling, we can either target each corner individually, or all the corners at once. In order to easily append a border radius setting to all the corners at once, we would create our CSS properties as follows:

#example {
background-color:#ff0000; // Red background
width: 200px;
height: 200px;
border-radius: 10px;

The preceding CSS not only appends a 10px border radius to all of the corners of the #example element, by using all the properties, which the modern browsers use, we can be assured that the effect will be visible to all users attempting to view this content:

As mentioned above, each of the individual corners of the element can be targeted to only append the radius to a specific part of the element:

#example {
border-top-left-radius: 0px; // This is doing nothing
border-top-right-radius: 5px;
border-bottom-right-radius: 20px;
border-bottom-left-radius: 100px;

The preceding CSS now removes our #example element's left border radius by setting it to 0px and sets a specific radius to each of the other corners. It's worth noting here that setting a border radius equal to 0 is no different than leaving that property completely out of the CSS styles:


Dealing with customized fonts in Flash has had its ups and downs over the years. Any Flash developer who has needed to incorporate and use customized fonts in their Flash applications probably knows the pain that comes with choosing a font embedding method as well as making sure it works properly for users who don't have the font installed on their computer viewing the Flash application.

CSS3 font embedding has implemented a "no fuss" way to include custom fonts into your HTML5 documents with the addition of the @font-face declaration:

@font-face {
font-family: ClickerScript;
src: url('ClickerScript-Regular.ttf'),
url('ClickerScript-Regular .otf'),
url('ClickerScript-Regular .eot');

CSS can now directly reference your TTF, OTF, or EOT font which can be placed on your web server for accessibility. With the font source declared in our CSS document and a unique font-family identification applied to it, we can start using it on specific elements by using the font-family property:

#example {
font-family: ClickerScript;

Since we declared a specific font family name in the @font-face property, we can use that custom name on pretty much any element henceforth. Custom fonts can be applied to almost anything that contains text in your HTML document. Form elements such as button labels and text inputs also can be styled to used your custom fonts. You can even remake assets such as website logos in pure HTML and CSS with the same custom fonts used in the original asset creation.

Acceptable font formats

Like many of the other embedding methods for assets online, fonts needs to be converted into multiple formats to enable all common modern browsers to display them properly. Almost all of the available browsers will be able to handle the common True Type Fonts (.ttffile types) or Open Type Fonts (.otffile types), so embedding one of those two formats will be all that is needed. Unfortunately Internet Explorer 9 does not have support built in for either of those two popular formats and requires fonts to be saved in the EOT file format.

External font libraries

Many great services have appeared online in the last couple of years allowing web developers to painlessly prepare and embed fonts into their websites. Google's Web Fonts archive available at hosts a large set of open source fonts which can be added to your project without the need to worry about licensing or payment issues. Simply add a couple of extras lines of code into your HTML document and you are ready to go.

Another great site that is worth checking out is Font Squirrel, which can be found at Like Google Web Fonts, Font Squirrel hosts a large archive of web-ready fonts with the copy-and-paste-ready code snippets to add them to your document. Another great feature on this site is the @font-face generator which give you the ability to convert your preexisting fonts into all the web compatible formats.

Before getting carried away and converting all your favorite fonts into web ready formats and integrating them into your work, it is worth noting the End User License Agreement or EULA that came with the font to begin with. Converting many available fonts for use on the web will break license agreements and could cause legal issues for you down the road.


More commonly known as "alpha" to the Flash developer, setting the opacity of an element not only allows you to change the look and feel of your designs, but allows you to add features like content that fades in and out. As simple as this concept seems, it is relatively new to the available list of CSS properties available to web developers. Setting the opacity of an element is extremely easy and looks something like the following:

#example {
opacity: 0.5;

As you can see from the preceding example, like ActionScript 3, the opacity value is a numerical value between 0 and 1. The preceding example would display a element at 50 percent transparency. The opacity property in CSS3 is now supported in all the major browsers, so there is no need to worry about using alternative property syntax when declaring it.

RGB and RGBA coloring

When dealing with color values in CSS, many developers would typically use hexadecimal values, which would resemble something like #000000 to declare the usage of the color black. Colors can also be implemented in their RGB representation in CSS by utilizing the rgb() or rgba() calls in place of the hexadecimal value. As you can see by the method name, the rgba color lookup in CSS also requires a forth parameter which declares the colors alpha transparency or opacity amount. Using RGBA in CSS3 rather than hexadecimal colors can be beneficial for a couple of reasons. Consider you have just created a div element which will be displayed on top of existing content within your web page layout.

If you ever wanted to set a background color to the div as a specific color but wish for only that background to be semi transparent and not the interior content, the RGBA color declaration now allows you to do this easily as you can set the colors transparency:

#example {
// Background opacity
background: rgba(0, 0, 0, 0.5); // Black 50% opacity

// Box-shadow
box-shadow: 1px 2px 3px 4px rgba(255, 255, 255, 0.8); // White 80%
// Text opacity
color: rgba(255, 255, 255, 1); // White no transparency
color: rgb(255, 255, 255); // This would accomplish the same

// Text Drop Shadows (with opacity)
text-shadow: 5px 5px 3px rgba(135, 100, 240, 0.5);

As you can see in the preceding example, you can freely use RGB and RGBA values rather than hexadecimal anywhere color values are required in CSS syntax.

Element transforms

Personally, Ifind CSS3 transforms to be one of the most exciting and fun new features in CSS. Transforming assets in the Flash IDE as well as with ActionScript has always been easily accessible and easy to implement. Transforming HTML elements is a relatively new feature to CSS and is still gaining full support by all the modern browsers.

Transforming an element allows you to manipulate its shape and size by opening up a ton of possibilities for animations and visual effects to assets without the need to prepare the source before hand. When we refer to "transforming an element", we are actually describing a number of properties that can be applied to the transformation to give it different characteristics. If you have transformed objects in Flash or possibly in Photoshop before, these properties may be familiar to you.


As a Flash developer used to primarily dealing with X and Y coordinates when positioning elements, the CSS3 Translate Transform property is a very handy way of placing elements and it works on the same principal. The translate property takes two parameters which are the X and the Y values to translate, or effectively move the element:

transform:translate(-25px, -25px);

Unfortunately, to get your transforms to work in all browsers, you will need to target each of them when you append transform styles. Therefore, the standard transform style and property would now look something like this:

transform:translate(-25px, -25px);
-ms-transform:translate(-25px, -25px); /* IE 9 */
-moz-transform:translate(-25px, -25px); /* Firefox */
-webkit-transform:translate(-25px, -25px); /* Safari and Chrome */
-o-transform:translate(-25px, -25px); /* Opera */


Rotation is pretty self-explanatory and extremely easy to implement. The rotate properties take a single parameter to specify the amount of rotation, in degrees, to apply to the specific element:

-ms-transform:rotate(45deg); /* IE 9 */
-moz-transform:rotate(45deg); /* Firefox */
-webkit-transform:rotate(45deg); /* Safari and Chrome */
-o-transform:rotate(45deg); /* Opera */

It is worth noting that regardless of the fact that the supplied value is always intended to be a value in degrees, the value must always have deg appended for the value to be properly recognized.


Just like rotate transforms, scaling is pretty straightforward. The scale property requires two parameters, which declare the scale amount for both X and Y:

transform:scale(0.5, 2);
-ms-transform:scale(0.5, 2); /* IE 9 */
-moz-transform:scale(0.5, 2); /* Firefox */
-webkit-transform:scale(0.5, 2); /* Safari and Chrome */
-o-transform:scale(0.5, 2); /* Opera */


Skewing a element will result in the angling of the X and Y axes:

transform:skew(10deg, 20deg);
-ms-transform:skew(10deg, 20deg); /* IE 9 */
-moz-transform:skew(10deg, 20deg); /* Firefox */
-webkit-transform:skew(10deg, 20deg); /* Safari and Chrome */
-o-transform:skew(10deg, 20deg); /* Opera */

The following illustration is a representation of skewing an image with the preceding properties:


The matrix properties combine all of the preceding transforms into a single property and can easily eliminate many extra lines of CSS in your source:

transform:matrix(0.586, 0.8, -0.8, 0.586, 40, 20);
/* IE 9 */
-ms-transform:matrix(0.586, 0.8, -0.8, 0.586, 40, 20);
/* Firefox */
-moz-transform:matrix(0.586, 0.8, -0.8, 0.586, 40, 20);

/* Safari and Chrome */
-webkit-transform:matrix(0.586, 0.8, -0.8, 0.586, 40, 20);
/* Opera */
-o-transform:matrix(0.586, 0.8, -0.8, 0.586, 40, 20);

The preceding example utilizes the CSS transform matrix property to apply multiple transform styles in a single call. The matrix property requires six parameters to rotate, scale, move, and skew the element. Using the matrix property is only really useful when you actually need to implement all of the transform properties at once. If you only need to utilize one aspect of element transforms, you will be better off using just that CSS style property.

3D transforms

Up until now, all of the transform properties we have reviewed have been two dimensional transformations. CSS3 now also supports 3D as well as 2D transforms.One of the best parts of CSS3 3D transforms is the fact that many devices and browsers support hardware acceleration allowing this complex graphical processing to be done on your video cards GPU. At the time of writing this, only Chrome, Safari, and firefox have support for CSS 3D transforms.

Interested in what browsers will support all these great HTML5 features before you start developing? Check out to see what popular browsers support in a simple, easy-to-use website.

When dealing with elements in a 3D world, we make use of the Z coordinate, which allows the use of some new transform properties.


Let's create a 3D cube from HTML elements to put all of these properties into a working example. To start creating our 3D cube, we will begin by writing the HTML elements which will contain the cube as well as the elements which will be making up the cube itself:

<div class="container">
<div id="cube">
<div class="front"></div>
<div class="back"></div>
<div class="right"></div>
<div class="left"></div>
<div class="top"></div>
<div class="bottom"></div>

This HTML creates a simple layout for our cube by not only creating each of the six sides, which makes up a cube with specific class names, but the container for the entire cube as well as the main container to display all of our page content. Of course, since there is no internal content in these containers and no styling yet, opening this HTML file in your browser would yield an empty page. So let's start writing our CSS to make all of these elements visible and position each to form our three dimensional cube. We will start by setting up our main containers which will position our content and contain our cubes sides:

.container {
width: 640px;
height: 360px;
position: relative;
margin: 200px auto;

/* Currently only supported by Webkit browsers. */
-webkit-perspective: 1000px;
perspective: 1000px;
#cube {
width: 640px;
height: 320px;
position: absolute;

Let the transformed child elements preserve
the 3D transformations:
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;

The container class is our main element, which contains all of the other elements within this example. After appending a width and height, we set the top margin to 200px to push the display down the page a bit for better viewing and the left and right margins to auto which will align this element in the center of the page:

#cube div {
display: block;
position: absolute;
border: 1px solid #000000;
width: 640px;
height: 320px;

By defining properties to the #cube div, we set the styles to every div element within the #cube element. We are also kind of cheating the system of cube by setting the width and height to rectangular proportions as the intention is to add videos to each of the cube sides once we structure and position it.

With the basic cube-side styles appended, its time to start transforming each of the sides to form the three-dimensional cube. We will start with the front of the cube by translating it on the Z axis, bringing it closer to the perspective:

#cube .front {
-webkit-transform: translateZ(320px);
-moz-transform: translateZ(320px);
transform: translateZ(320px);

In order to append this style to our element in all modern browsers, we will need to specify the property in multiple syntaxes for each browser that doesn't support the default transform property:

The preceding screenshot shows what has happened to the .front div after appending a Z translation of 320px. The larger rectangle is the .front div, which is now 320px closer to our perspective. For simplicity's sake, let's do the same to the .back div and push it 320px away from the perspective:

#cube .back {

As you can see from the preceding code, to properly move the .back element into place without placing it upside down, we flip the element by 180 degrees on the X axis and then translate Z by 320px just like we did for .front. Note that we didn't set a negative value on the translate Z because the element was flipped. With the .back CSS styles in place, our cube should look like the following:

Now the smallest rectangle visible is the element with the classname .back, the largest is our .front element, and the middle rectangle is the remaining elements to be transformed.

To position the sides of our cubes we will need to rotate the side elements on the Y axis to get them to face the proper direction. Once they are rotated into place, we can translate the position on the Z axis to push it out from the center as we did with the front and back faces:

#cube .right {
-webkit-transform: rotateY(90deg) translateZ( 320px );
-moz-transform: rotateY(90deg) translateZ( 320px );
transform: rotateY(90deg) translateZ( 320px );

With the right side in place, we can do the same to the left side but rotate it in the opposite direction to get it facing the other way:

#cube .left {
-webkit-transform: rotateY(-90deg) translateZ( 320px );
-moz-transform: rotateY(-90deg) translateZ( 320px );
transform: rotateY(-90deg) translateZ( 320px );

Now that we have all four sides of our cube aligned properly, we can finalize the cube positioning by aligning the top and bottom sides. To properly size the top and bottom we will set their own width and height to override the initial values set in the #cube div styles:

#cube .top {
width: 640px;
height: 640px;

-webkit-transform: rotateX(90deg) translateZ( 320px );
-moz-transform: rotateX(90deg) translateZ( 320px );
transform: rotateX(90deg) translateZ( 320px );
#cube .bottom {
width: 640px;
height: 640px;

-webkit-transform: rotateX(-90deg) translateZ( 0px );
-moz-transform: rotateX(-90deg) translateZ( 0px );
transform: rotateX(-90deg) translateZ( 0px );

To properly position the top and bottom sides, we rotate the .top and .bottom elements +-90 degrees on the X axis to get them to face up and down, and only need to translate the top on the Z axis to raise it to the proper height to connect with all of the other sides.

With all of those transforms appended to our layout, the resulting cube should look like the following:

Although it looks 3D, since there is nothing in the containers, the perspective isn't really showing off our cube very well. So let's add some content such as a video in each of the sides of the cube to get a better visualization of our work. Within each of the sides, let's add the same HTML5 video element code:

<video width="640" height="320" autoplay="true" loop="true">
<source src = "cube-video.mp4" type="video/mp4">
<source src = "cube-video.webm" type="video/webm">
Your browser does not support the video tag.

Since we have not added the element playback controls in order to display more visible area of the cube, our video element is set to autoplay the video as well as loop the playback on completion. Now we get a result that properly demonstrates what 3D transforms can do and is a little more visually appealing:

Since we set the opacity of each of the cube sides, we can now see all four videos playing on each side, pretty cool! Since we are already here, why not kick it up one more notch and add user interaction to this cube so we can spin it around and see the video on each side.

To perform this user interaction, we need to use JavaScript to translate the mouse coordinates on the page document to the X and Y 3D rotation of our cube. So let's start by creating the JavaScript to listen for mouse events:

window.addEventListener("load", init, false);
function init() {
// Listen for mouse movement
window.addEventListener('mousemove', onMouseMove, false);
function onMouseMove(e) {
var mouseX = 0;
var mouseY = 0;
// Get the mouse position
if (e.pageX || e.pageY) {
mouseX = e.pageX;
mouseY = e.pageY;
} else if (e.clientX || e.clientY) {
mouseX = e.clientX + document.body.scrollLeft +
mouseY = e.clientY + document.body.scrollTop +
console.log("Mouse Position: x:" + mouseX + " y:" + mouseY);

As you can see from the preceding code example, when the mousemove event fires and calls the onMouseMove function, we need to run some conditionals to properly parse the proper mouse position. Since, like so many other parts of web development, retrieving the mouse coordinates differs from browser to browser, we have added a simple condition to attempt to gather the mouse X and Y in a couple of different ways.

With the mouse position ready to be translated into the transform rotation of our cube, there is one final bit of preparation we need to complete prior to setting the CSS style updates. Since different browsers support the application of CSS transforms in different syntaxes, we need to figure out, in JavaScript, which syntax to use during runtime to allow our script to run on all browsers. The following code example does just that. By setting a predefined array of the possible property values and attempting to check the type of each as an element style property, we can find which element is not undefined and know it can be used for CSS transform styles:

// Get the support transform property
var availableProperties = [
// Loop over each of the properties
for (var i = 0; i < availableProperties.length; i++) {
// Check if the type of the property style is a string (ie. valid)
if (typeof[availableProperties[i]] ==
// If we found the supported property, assign it to a variable
// for later use.
var supportedTranformProperty = availableProperties[i];

Now that we have the user's mouse position and the proper syntax for CSS transform updates for our cube, we can put it all together and finally have 3D rotational control of our video cube:

var supportedTranformProperty;
window.addEventListener("load", init, false);
function init() {
// Get the support transform property
var availableProperties = ['transform', 'MozTransform',
'WebkitTransform', 'msTransform', 'OTransform'];
for (var i = 0; i < availableProperties.length; i++) {
if (typeof document.documentElement.
style[availableProperties[i]] == 'string'){
supportedTranformProperty = availableProperties
// Listen for mouse movement
window.addEventListener('mousemove', onMouseMove, false);
function onMouseMove(e) {
// Get the mouse position
if (e.pageX || e.pageY) {
mouseX = e.pageX;
mouseY = e.pageY;
} else if (e.clientX || e.clientY) {
mouseX = e.clientX + document.body.scrollLeft +
mouseY = e.clientY + document.body.scrollTop +
// Update the cube rotation
rotateCube(mouseX, mouseY);
function rotateCube(posX, posY) {
// Update the CSS transform styles
document.getElementById("cube").style[supportedTranformProperty] =
'rotateY(' + posX + 'deg) rotateX(' + posY * -1 + 'deg)';

Regardless of the fact we have attempted to allow for multi browser use of this example, it is worth opening it up in each to see how something like 3D transforms with heavy internal content run. During the time of writing this, all WebKit browsers were the easy choice when viewing content like this, as browsers such as firefox and Internet Explorer render this example at a much slower and lower quality output:


With CSS3, we can add an effect when changing from one style to another, without using Flash animations or JavaScripts:

div {
transition: width 2s;
-moz-transition: width 2s; /* Firefox 4 */
-webkit-transition: width 2s; /* Safari and Chrome */
-o-transition: width 2s; /* Opera */

If the duration is not specified, the transition will have no effect, because the default value is 0:

div {
transition: width 2s, height 2s, transform 2s;
-moz-transition: width 2s, height 2s, -moz-transform 2s;
-webkit-transition: width 2s, height 2s, -webkit-transform 2s;
-o-transition: width 2s, height 2s,-o-transform 2s;

It should be worth noting that Internet Explorer currently does not have support for CSS3 transitions.

Browser compatibility

If you haven't noticed yet, the battle of browser compatibility is one of the biggest aspects of a web developer's job. Over time, many great services and applications have been created to help developers overcome these hurdles in a much simpler manner than trial-and-error techniques. Websites such as,, and are all great resources to keep on top of HTML5 specification developer and browser support for all the features within.

Frame rate

One would assume since you, the reader, are coming from a Flash development background, a moment should be taken to talk about frame rates or frames per second when developing HTML5 applications. Since every asset in Flash applications is based on the timeline model, calculating how many frames of that timeline are displayed every second is a pretty simple calculation. However, all the technologies that make up HTML5 development do not rely on the use of a timeline during runtime. Therefore calculating the frames per second or FPS value of a webpage is not always an accurate measure of performance of your HTML5 projects.

Developing for mobile

Another one of the driving forces behind the popularity of HTML5 is the overwhelming support for it on most of the modern mobile browsers ( With the loss of Flash Player on all mobile platforms now, the use of HTML5 to deliver content is at an all time high and the usage is growing daily. Applications, frameworks, and templates such as jQuery Mobile (, Phone Gap (, Appcelerator ( and the Mobile Boilerplate ( all of which will be covered in detail in the article, are all specifically built to aid web developers for building web content that is specifically targeted for mobile viewing. CSS can be set up in a responsive manner to allow the same page content to be displayed in an optimized format depending on the device and viewport configuration a user is viewing your content with.

Responsive layouts

The term "responsive layout" seems to get used on a more frequent basis as HTML5 development has grown in popularity. It has, to some, become a keyword to define one of the key features of good HTML5 development. Regardless of how the term is used, at the end of the day when we refer to "responsive layouts" in web development, we are referring to the usage of modern web development techniques to enable the same page content to transition its layout and content within it to adjust for the users device and viewing resolution. In other words, making sure your page content is set up in an optimized manner for all viewing resolutions and is able to transition between any one of the layouts without the need for content of page refreshing.

CSS Media Queries

One of the most important assets when creating responsive layouts is the use of CSS Media Queries. Media Queries allow you to target specific CSS styles depending on your user's device, resolution, rotation, and more. Knowing as much as possible about the device and software loading your HTML documents will allow you to not only specify how specific devices and browsers are to display your content, but it can also allow your code to monitor real-time changes to the viewing methods as well. For instance, the following Media Query example changes the background color depending on device rotation:

@media screen and (orientation:portrait) {
background-color: #FF0000;

@media screen and (orientation:landscape) {
background-color: #0000FF;

The list of CSS Media Queries properties is short but it is important to understand what is available to you when creating your conditions. Therefore, let's quickly review what properties you have at your disposal when writing your Media Queries:

  • width: Describes the width of the targeted display area.
  • height: Describes the height of the targeted display area.
  • device-width: Describes the width of the rendering display of the output device.
  • device-height : Describes the height of the rendering display of the output device.
  • orientation: Is portrait when the value of the height media feature is greater than or equal to the value of the width media feature. Otherwise the orientation is landscape.
  • aspect-ratio: Defined as the ratio of the value of the width media feature to the value of the height media feature.
  • device-aspect-ratio: Defined as the ratio of the value of the device-width media feature to the value of the device-height media feature.
  • color: Describes the number of bits per color component of the output device. If the device is not a color device, the value is zero.
  • color-index: Describes the number of entries in the color look up table of the output device. If the device does not use a color look up table, the value is zero.
  • monochrome: Describes the number of bits per pixel in a monochrome frame buffer. If the device is not a monochrome device, the output device value will be 0.
  • resolution: Describes the resolution of the output device, that is, the density of the pixels. When querying devices with non-square pixels, in min-resolution queries the least-dense dimension must be compared to the specified value and in max-resolution queries the most-dense dimensions must be compared instead. A resolution (without a "min-" or "max-" prefix) query never matches a device with non-square pixels.
  • scan: Describes the scanning process of "tv" output devices.
  • grid: Used to query whether the output device is grid or bitmap. If the output device is grid-based (for example, a "tty" terminal, or a phone display with only one fixed font), the value will be 1. Otherwise, the value will be 0.

Audio and video playback control

If you intend to use your multimedia in other forms than just a straightforward video playback element, you will need to understand the properties available for custom playback code integration.


By default, when an audio or video element is displayed in a HTML5 document, the source asset declared within it will be preloaded to allow for instantaneous playback when the user initiates the player. Assets will be preloaded only as far as the browsers deems necessary to enable fluid uninterrupted playback. To override this setting, we can use the preload parameter within the audio element to declare what we would like to be preloaded when a user views our page.

Setting the preload parameter to auto will preload the entire audio upon page load and could be a useful addition to any audio you are almost certain a user will watch at some point after the page loads. With the preload parameter set, our audio element would look something like the following:

<audio controls preload="all">
<source src = "my-audio .mp3" type="audio/mpeg">
<source src = "my-audio.ogg" type="audio/ogg">
Your browser does not support the audio element.

Aside from preloading everything, we can also preload absolutely nothing by setting preload="none" rather than auto. Removing preloading from audio will allow users to surf your pages without the need for unnecessary audio downloads but will result in longer loading times for audio to player once the user initiates the audio playback. Finally we can also just load audio metadata when preloading by setting preload="metatdata". This will allow the audio element to view what data it is about to load, which can be very useful when dynamically adding audio into an audio element and requiring the need to verify if it is fit for playback before attempting to do so.


The video will begin to play the moment it is able to do so without the need to stop the video for further buffering. Unlike many of the other element parameters in HTML, the autoplay parameter does not require a value. So just appending autoplay to the element will be enough to do the job. It is worth keeping in mind that the autoplay setting will be ignored when loaded on almost all mobile browsers. Mobile browsers tend to ignore this setting in an attempt to conserve bandwidth on a wireless connection.


With the loop setting appended to the audio element, the video will restart every time is finishes. Like the autoplay parameter, the loop parameter does not require a value. If you only wanted a video to loop a specific number of times, you can either watch how many times its loops with the loop parameter set and then remove it when necessary, or control the entire playback from JavaScript to control the loop count without the loop parameter in the video element.

Sound effects

Playing a sound effect at a specific moment can be accomplished in a number of ways with the use of the HTML5 audio element and JavaScript. In its simplest form, playing sound effects can be implemented as done the following code example:

<audio src = "audio/ping.mp3" preload="auto" id="audio-ping">
window.addEventListener("load", init, false);
function init() {
function onMouseDown(e) {

When the audio element is created inside the HTML document body, we set the preload="auto" which will make sure the audio is preloaded completely as soon as possible. We do this so there is no latency when the sound is needed during the effect event. The audio element is also given an ID to enable referencing in JavaScript a couple line down. With the window load event listener, we wait for page load then apply an event listener to any mousedown event anywhere in the browser window. When this fires, we select our audio element by ID and call the built in play() method resulting in the audio playback on every click of the browser window.

Media playback manipulation

Aside from the play() method in the preceding example, JavaScript has the accessibility to control much more of the audio and video element directly. Audio volume can be set as a value between 0 and 1 as shown in the following example:

document.getElementById('audio-ping').volume = 0.5; // Set the volume
to 50%

We can also gather all the stats on the element by utilizing the following exposed objects within it:

var media = document.getElementById('audio-ping');
media.seekable.start(); // Start time (seconds)
media.seekable.end(); // End time (seconds)
media.currentTime = 20; // Seeks playback to 20 seconds
// Total amount of seconds the playback has displayed

Reading local files with the file API

Another feature that brings HTML5 content into a more application-like feature set is the addition of the file API. Users can now interact with their local content on a much more in depth level than ever before. Users can import files in the traditional HTML form manner or now just drag the file into specified drop zones in your HTML5 layouts. Once a file has been submitted to the web page by the user, your JavaScript file API usage can allow you to view, edit, and manipulate the file data prior to ever submitting it to the server.

Web Workers

In the past when executing processor intensive JavaScript, browsers would often tend to freeze until the processing had been completed and the results were returned. With the advent of HTML5 Web Workers, you can now execute your processor intensive JavaScript code as a background process that will not affect the performance of the active document. Users will be able to continue using the site as intended as they wait for the Web Worker to complete its jobs in the background.

To easily check if a user's browser has support for HTML5 Web Workers, we can check if the type of the Worker object is undefined or not:

if(typeof(Worker) == "undefined") {
// This browser doesn't support Web Workers...

Depending on whether the browser supports the usage of Web Workers, we can easily create a new worker at anytime by instantiating a new Worker object and a reference to its JavaScript source:

worker = new Worker("worker.js");

In the preceding example, we created a new worker and referenced it to the source within the worker.jsfile. The next step is to create the event listener for when the worker posts an update. To create this listener, we create a function on the onmessage property and retrieve the message from the property:

// Create an event listener for worker updates.
worker.onmessage = function (event) {
console.log('New worker event - ' +;

The code within the worker can be anything, although it makes the most sense for it to be something that would normally freeze the browser for a short period of time. Regardless of what your worker is doing, to enable the callback to your code you will use the postMessage built-in function:


Since your Web Worker code is located in external files, it will not have access to the window, document or parent object in its JavaScript source.


Adding server-side communication to your web pages to enable features such as multiuser interactivity or push notifications is becoming more and more popular with the advent of WebSockets. To put it in a nutshell, WebSockets fill the void when you need a server to communicate with the client without requiring the client's request.

When building Flash applications, typically one would use technologies and frameworks such as Real-Time Media Flow Protocol (RTMFP) or SmartFoxServer ( to allow for server-based multiuser applications. This concept is now available with the use of WebSockets and is a true testament to how far the development of the HTML specification has come.

The Canvas element

We can't finish this article without at least beginning to make mention of the HTML5 Canvas element. The Canvas allows developers to use the Canvas 2D Drawing API to draw graphics on the fly into an empty controllable area. From the perspective of a Flash developer, the easiest way to understand the Canvas elements feature set is that it uses similar features to the ActionScript 3 Drawing and Graphics API within an empty area in the HTML layout which is very similar to the Flash Stage.

To better understand what all the fuss is about, let's create a simple drawing application with the use of the Canvas. To begin, we need to append the Canvas element into the body of our HTML document. There is no content required to be inside the element's tags, as it will only be viewable when the user is attempting to view this content from a browser without the support for the Canvas element:

<canvas id="example" width="640" height="480" style="border:1px
solid #000000;">
Your browser does not support the HTML5 Canvas element.

Two important additions have been appended to the Canvas in this example and they are the element ID, which will be used in JavaScript in the following steps, as well as the width and height declaration. Without the width and height set in the element, most browsers will render the Canvas at 300px x 150px. To aid us in the development of this application, a 1px border has been added to the Canvas to allow us to see exactly where its boundaries are within the browser window. Finally as mentioned, the internal content within the Canvas element will only display if the element is not supported within the browser rendering it. If the application has been also written as a Flash application, the object embed for the Flash SWF could be used in place of the text warning we are using in this example.

The next step is to set up the reference to our Canvas and its 2D context within JavaScript, and since we set an ID on our element, we can easily reference it to a variable within our code:

var canvas, context; // Variables to hold Canvas references
window.addEventListener("load", init, false);
function init() {
// Set the canvas reference to a JavaScript variable.
canvas = document.getElementById('example');
// Get the 2D canvas context to allow for 2D Drawing API integration
context = canvas.getContext('2d');
if(!context) {
alert("Failed to get canvas context!");

canvas.addEventListener('mousemove', onMouseMove, false);
canvas.addEventListener('mousedown', onMouseDown, false);
canvas.addEventListener('mouseup', onMouseUp, false);

function onMouseDown(e) {
isDrawing = true;
function onMouseUp(e) {
isDrawing = false;

With our Canvas referenced and mouse event listeners set up to watch for when the user has the mouse button down, let us finalize this example by writing our onMouseMove function to draw a line when the isDrawing variable is true:

function onMouseMove(e) {
var x, y;
if (e.pageX || e.pageY) {
x = e.pageX;
y = e.pageY;
} else if (e.clientX || e.clientY) {
x = e.clientX + document.body.scrollLeft +
y = e.clientY + document.body.scrollTop +
if(!isDrawing) {
// Since the mouse isn't down, just move
// the context to the latest mouse position.
context.moveTo(x, y);
} else {
// The mouse is down so draw the line to
// the current mouse position.
context.lineTo(x, y);

If you notice, the initial code in our onMouseMove function is taken from our 3D Transforms example and allows us to read the mouse X and Y position on the different modern browsers. The condition following the mouse position lookup should look semi-familiar if you had used the Drawing API in ActionScript 3. Assuming the mouse is down, we draw a line to the current mouse position and set the default stroke on it. In this case, the default stroke is a 1px black solid line. When the mouse is not down, we simply move the context to the mouse position but do not draw any lines. This allows us to constantly reset and wait for a new line to be started. When tested in the browser, this example will look something like this:

This example really is only the start of what is available to developers but hopefully gives you an idea of how it works.

Stage3D versus WebGL

Before we end this article, some mention should be made about the availability of WebGL and its similarities and differences to Stage3D in Adobe Flash. WebGL is a cross-platform web standard which allows developers to create and manipulate low-level 3D graphics, bringing plugin-free 3D development to the Web. WebGL can be implemented and viewed in all modern browsers, an exception is Internet Explorer.

Take note that it seems Microsoft is planning to release Internet Explorer 11 with WebGL support.

The key aspects of WebGL and Stage 3D are that they both support the use of hardware acceleration. This can drastically increase the performance of graphical processing loads when viewing content on devices and browsers with proper support.

For more information and to see if your current web browser supports the use of WebGL, head over to http://, the WebGL public wiki (, or view some intriguing examples at


Although we have covered a ton of interesting features during the course of this article. The key thought to take away from what we have covered so far is how the relationships between features in Flash and HTML5 are similar yet different at the same time. Understanding what technology will be able to allow you to develop your applications in the best possible manner is a key trait for any good developer.

Resources for Article:

Further resources on this subject:

You've been reading an excerpt of:

HTML5 for Flash Developers

Explore Title