(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 (http://modernizr.com) 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.
box-shadow
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:
text-shadow
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:
border-radius
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:
Fonts
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 http://www.google.com/webfonts 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 http://www.fontsquirrel.com. 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.
Opacity
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% opacity // Text opacity color: rgba(255, 255, 255, 1); // White no transparency color: rgb(255, 255, 255); // This would accomplish the same styling // 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.
Translate
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 */
Rotate
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:
transform:rotate(45deg);-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.
Scale
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 */
Skew
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:
Matrix
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 http://caniuse.com 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.
transform:rotateX(angle)transform:rotateY(angle)transform:rotateZ(angle)transform:translateZ(px)transform:scaleZ(px)
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:
<body> <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> </div> </div></body>
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; opacity:0.8;}
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 { -webkit-transform: rotateX(-180deg) rotate(-180deg) translateZ(320px); -moz-transform: rotateX(-180deg) rotate(-180deg) translateZ(320px); transform: rotateX(-180deg) rotate(-180deg) translateZ(320px);}
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.</video>
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 + document.documentElement.scrollLeft; mouseY = e.clientY + document.body.scrollTop + document.documentElement.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 propertyvar availableProperties = [ 'transform', 'MozTransform', 'WebkitTransform', 'msTransform', 'OTransform' ];// Loop over each of the propertiesfor (var i = 0; i < availableProperties.length; i++) { // Check if the type of the property style is a string (ie. valid) if (typeof document.documentElement.style[availableProperties[i]] == 'string'){ // 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:
<script> 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 + document.documentElement.scrollLeft; mouseY = e.clientY + document.body.scrollTop + document.documentElement.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)'; }</script>
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:
Transitions
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 http://css3test.com, http://caniuse.com, and http://html5readiness.com are all great resources to keep on top of HTML5 specification developer and browser support for all the features within.
Read more