The latest incarnations of HTML and CSS offer many new features. For example, HTML5 includes new elements that make web pages more semantic; you can now store data offline, create editable content areas, use drag-and-drop functionality, and much more. With CSS3, you can create round corners without graphics as well as add shadows and gradients. Although many exciting new features are becoming available, not all of the changes work across browsers. This article provides specific HTML5 and CSS3 techniques that you can use right now on all of the latest versions of the major browsers, including Apple Safari, Windows® Internet Explorer®, Mozilla Firefox, and Google Chrome.
In particular, some versions of Internet Explorer need a little help
recognizing the new HTML5 elements. Luckily, a publicly available
JavaScript file called html5shim—an HTML5 Internet
Explorer-enabling script—helps it recognize and style HTML5
elements that are not otherwise rendered properly. To include this
JavaScript file, simply include the code shown in Listing
1 in the <head> block of your
HTML file above any CSS you are using.
Listing 1. html5shim, an HTML5 Internet Explorer-enabling script
<!--[if lt IE 9]> <script type="text/javascript" src="http://html5shim.googlecode.com/svn/trunk/ html5.js"></script> <![endif]--> |
This code also prevents browsers that do not need it from loading the extra file, limiting the load to Internet Explorer 8 or earlier. You can learn more about the JavaScript library by visiting the project website. (See Resources for a link.)
In addition to the many new elements being introduced in HTML5, its new functionality is noticeable. This section covers some of the new HTML5 elements and shows how to create editable content areas and post messages between one page and another.
If you've spent a lot of time structuring HTML websites, you know that many
common sections are used repeatedly. These usually include a header for a
logo or other identifying information, navigation that lists sections of
the website, and a footer with copyright information. In previous versions
of HTML, it was common to use the id attribute
to identify these elements; for example, a header might be contained by a
<div>, with an id set to "header"—that is, <div
id="header">.
With HTML5, you can use new tags to define these specific areas without
writing additional identifying attributes. For example, use the new header element in place of a <div> with a header id. This
is not only a more logical way to code, but it can also be helpful when
looking at another developer's web page, since many developers have
different coding styles. Of course, the id
attribute is still useful in many situations, but it's no longer necessary
with these common elements. Listing 2 gives an
example of a basic HTML5 page, using the header, nav, section, article, aside, and footer
elements.
Listing 2. A basic HTML5 page structure
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Cross-browser HTML5 and CSS3</title>
<!--[if lt IE 9]>
<script type="text/javascript" src="http://html5shim.googlecode.com/svn/trunk/
html5.js"></script>
<![endif]-->
</head>
<body>
<header>
<nav>
<!--Navigation-->
</nav>
</header>
<section id="intro">
<header>
<h2>Cross-browser HTML5 and CSS3</h2>
</header>
<div>Lorem ipsum</div>
</section>
<section id="content">
<section id="articles">
<article>
<header>
<h2>Article title</h2>
<p>Posted on <time datetime="2009-09-04T16:31:24+02:00">
September 4th 2009
</time></p>
</header>
<div>Pellentesque habitant morbi tristique senectus et netus et
malesuada fames ac turpis egestas.</div>
<h2>Comments</h2>
<form id="comment-form">
<input type="text" name="comment" id="comment" />
<input type="submit" value="submit" />
</form>
</article>
</section>
<aside>
<h2>About section</h2>
<p>Donec eu libero sit amet quam egestas semper. Aenean ultricies mi
vitae est. Mauris placerat eleifend leo.</p>
</aside>
</section>
<footer>Copyright notice</footer>
</body>
</html>
|
Each element is fairly self-explanatory, but several things should be pointed out:
- HTML5 only has one doctype:
<!doctype html>. - The
header,nav, andfooterare all exactly what you'd anticipate. - You can use the
sectionelement to help define sections of a web page layout—for example, an article or an intro. - You can use the
articleelement to identify an individual blog post, comment, etc. - You can use the
asideelement as a sidebar; its main purpose is to wrap around main page content.
To get the aside element to appear next to the
main page content, make sure that the width of each works with the current
page width, and position the elements. Floats were once a common way to
get two elements to appear side-by-side, but with the section and aside elements, you can
now stop using floats by introducing table and table cell display values,
as shown in Figure 1.
Figure 1. HTML5 page layout
Listing 2 shows how to set the content section to display as a table and the articles section and <aside> tag to display as a table cell. This way, the
entire structure acts as a table without all the extraneous table code and
the table cells sitting next to each other like columns. Listing 3 gives an example of how to write the CSS to display
these elements side-by-side.
Listing 3. Using table values for display
#content {
display: table;
}
#articles {
display: table-cell;
width: 620px;
padding-right: 20px;
}
aside {
display: table-cell;
width: 300px;
}
|
Creating editable content areas
Another interesting HTML5 feature is ContentEditable. As Listing 4 shows, any
element that uses the ContentEditable attribute
becomes editable. This means that you can edit any text within the element
without having to use a finicky form element.
Figure 2 gives an example of the ContentEditable attribute in action.
Figure 2. Editable content areas
With Ajax, you can easily save any updates to a database, and with HTML5's local storage functionality working across browsers, you can take this powerful functionality offline.
Listing 4. Creating an editable HTML element
<div id="editable" contenteditable="true"> Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. </div> |
Message posting is a new addition that brings a lot of possibilities. Listing 5 and Listing 6 give examples of how to post messages from a main web page to an iframe within that page.
Listing 5. Posting messages
<form id="comment-form">
<input type="text" name="comment" id="comment" />
<input type="submit" value="submit" />
<iframe id="comment-iframe" src="post-message.html"></iframe>
</form>
<script type="text/javascript" src="assets/js/event.js"></script>
<script type="text/javascript">
var win = document.getElementById("comment-iframe").contentWindow;
addEvent(document.getElementsByTagName('form')[0], 'submit', function (e) {
if (e.preventDefault) e.preventDefault();
win.postMessage(document.getElementById("comment").value,
"http://studiosedition.com");
// otherwise set the returnValue property of the original event to false (IE)
e.returnValue = false;
return false;
});
</script>
|
A JavaScript function named postMessage handles
the actual message posting; you use a new event named message in the iframe to retrieve the event and the associated
properties.
Listing 6. Retrieving posted messages
<p id="post-comment"></p>
<script type="text/javascript" src="assets/js/event.js"></script>
<script type="text/javascript">
addEvent(window, "message", function(e){
if(e.origin !== "http://studiosedition.com") {
document.getElementById("post-comment").innerHTML = 'Message from ' + e.origin;
}
else
{
document.getElementById("post-comment").innerHTML = e.origin + " : " + e.data;
}
});
</script>
|
This example uses a custom JavaScript event function that is included as an external file named event.js. Listing 7 shows this script.
Listing 7. A custom event function
var addEvent = (function () {
if (document.addEventListener) {
return function (el, type, fn) {
if (el && el.nodeName || el === window) {
el.addEventListener(type, fn, false);
} else if (el && el.length) {
for (var i = 0; i < el.length; i++) {
addEvent(el[i], type, fn);
}
}
};
} else {
return function (el, type, fn) {
if (el && el.nodeName || el === window) {
el.attachEvent('on' + type, function () {
return fn.call(el, window.event);
});
} else if (el && el.length) {
for (var i = 0; i < el.length; i++) {
addEvent(el[i], type, fn);
}
}
};
}
})();
|
CSS3 is adding an entirely new realm of possibilities for web designers. You can now add shadows, gradients, rotation, and certain fonts—all without having to use images that weigh down a web page. This section introduces some new, exciting features that you can use immediately without any cross-browser issues. Web designers can now spend more time creating eye-catching websites instead of trying to identify how to make something look right.
Shadows add dimension to a web page; this was previously possible only with images. With CSS3, you can control many details, including the direction, offset, color, and blur of the shadow (shown in Figure 3). Listing 8, Listing 9, and Listing 10 give examples of the various ways you can use CSS to create a shadow.
Figure 3. Rendering a shadow with CSS3
In Firefox, use the -moz-box-shadow to apply a
shadow to an element. You can assign four values to this property.
Listing 8. Creating a shadow in Firefox
-moz-box-shadow: 1px 1px 4px #666; |
In Safari and Chrome, use -webkit-box-shadow to
apply a shadow to an element. You can assign four values to this property
as well.
Listing 9. Creating a shadow in Safari and Chrome
-webkit-box-shadow: 1px 1px 4px #666; |
Four properties are available for Safari, Chrome, and Firefox shadows:
- Horizontal offset of the shadow. The offset number can be positive or negative; if it's negative, the offset casts the shadow to the left of the element, while a positive value casts the shadow to the right.
- Vertical offset. This offset can also be set to a negative or positive number. A negative value casts the shadow above the element, while a positive value casts it below.
- Blur radius. Higher numbers increase the amount of blur you see, while lower numbers sharpen the shadow.
- Hex color. You can set the hex color of the shadow.
The CSS is different when working with Internet Explorer. Listing 10 shows how to create a shadow in Internet Explorer using filters. The first filter is for versions 6 and 7, while the second filter is for versions 8 and later.
Listing 10. Internet Explorer CSS filters for creating shadows
filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=0px, OffY=2px, Color='#333333'); -ms-filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=0px, OffY=2px, Color='#333333')"; |
Many ways to create gradients have been popularized over the years; my favorite is the 1px repeating gradient image. Figure 4 shows that with CSS3, this technique is longer necessary, since each browser type now has its own way of handling gradients (shown in Listing 11, Listing 12, and Listing 13).
Figure 4. Rendering a gradient with CSS3
You can handle the display of a gradient in several ways. Listing 11 gives a simple Firefox example that starts from the top and fades from the first to the second color.
Listing 11. Creating a gradient in Firefox
background: -moz-linear-gradient(top, #eaeaea, #999999); |
The Safari and Chrome example in Listing 12 results in the same look as the Firefox example, but is written differently:
- The first property is the type, which allows you to set the gradient to linear or radial.
- The second and third properties are the start and the end points of the gradient, respectively.
- The fourth and fifth properties are the start and end colors of the gradient, respectively.
Listing 12. Creating a gradient in Safari and Chrome
background: -webkit-gradient(linear,left top,left bottom,color-stop(0, #eaeaea), color-stop(1, #999999)); |
Internet Explorer requires a filter to create a gradient. The filter has a number of associated properties:
Enabledindicates whether the filter is enabled. (The default is True.)EndColordetermines the final opaque color of the gradient.EndColorStrdetermines the final color of the gradient.GradientTypedetermines the orientation of the gradient.StartColordetermines the initial opaque color of the gradient.StartColorStrdetermines the initial color of the gradient.
Listing 13 uses the simplest form of the gradient filter, defining a start and end color.
Listing 13. Creating a gradient in Internet Explorer
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eaeaea', endColorstr='#999999'); |
Sometimes, the normal horizontal display of an element is not enough. With the introduction of transform, you can now rotate an element in CSS3 (as shown in Figure 5). Whether you need an element to be completely flipped on its side or a little angle to fit your design, it's possible across browsers with the code shown in Listing 14, Listing 15, and Listing 16.
Figure 5. Rotating an HTML element with CSS3
The code to rotate an element is straightforward: simply use a number and
deg to indicate the degree. In Firefox, use
-moz-transform to rotate an element, as the
code in Listing 14 shows.
Listing 14. Rotating an element in Firefox
-moz-transform:rotate(-2deg); |
In Safari and Chrome, use -webkit-transform to
rotate an element.
Listing 15. Rotating an element in Safari and Chrome
-webkit-transform:rotate(-2deg); |
You have several options when rotating an element in Internet Explorer. If the first transform method doesn't work, you can always fall back to filters. The filter to rotate an element in Internet Explorer is Matrix. While it might be a little complicated to use, it does do the job when necessary.
The Matrix filter has a number of associated properties:
Dxgives the X component for linear transformations.Dygives the Y component for linear transformations.Enabledis used to enable the filter.FilterTypeis used to set the pixels of the transformed content.M11determines the first row/first column entry for linear transformations.M12determines the first row/second column entry for linear transformations.M21determines the second row/first column entry for linear transformations.M22determines the second row/second column entry for linear transformations.SizingMethodis used to determine whether the container is resized to fit the result.
Listing 16. Rotating an element in Internet Explorer
-ms-transform: rotate(-2deg); filter: progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=0.9914448613738104, M12=-0.13052619222005157, M21=0.13052619222005157, M22=0.9914448613738104); -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.9914448613738104, M12=-0.13052619222005157, M21=0.13052619222005157, M22=0.9914448613738104, sizingMethod='auto expand')"; |
All browsers use the W3C box model, and with CSS3, you can use box-sizing to set the way the browser renders an
element's width and height. The border-box
element tells the browser to use the actual width and height without
taking into account the padding and border. Listing
17 shows box sizing in Safari and Chrome.
Listing 17. Box sizing in Safari and Chrome
-webkit-box-sizing: content-box; |
In Listing 18, notice that the only difference
between Safari/Chrome and Firefox box sizing is that Firefox uses the
-moz-box-sizing property.
Listing 18. Box sizing in Firefox
-moz-box-sizing: content-box; |
Internet Explorer uses the -ms-box-sizing
property, as shown in Listing 19.
Listing 19. Box sizing in Internet Explorer
-ms-box-sizing: content-box; |
The default for some browsers prompts them to take the padding and border into account when setting the width of an element, which results in the equation (width or height) + padding + border.
Borders are a common way to define an area of a web page. The new outline element allows the same possibilities as
a border but with the addition of an offset. In Listing
20, notice that the offset lets you create an outline and offset
it from the actual bounds of the element. In the past, this was only
achievable by adding a border and padding to an element, which didn't
always produce the expected results.
Listing 20. Outlining and offsetting the outline on an element
outline: 1px dotted #cccccc; outline-offset: 10px; |
Many pseudo-classes are already in use; most are commonly associated with anchor tags for hyperlinks. Pseudo-classes let you add different states to an element and change properties based on the current state. Listing 21 shows common usage for pseudo-classes.
Listing 21. Common usage of pseudo-classes
a:link { }
a:visited { }
a:hover { }
a:active { }
|
The pseudo selector shown in Listing 22 creates a hover state for the editable HTML5 content area and applies the previously covered outline code.
Listing 22. Working with pseudo selectors
#editable:hover {
outline: 1px dotted #cccccc;
outline-offset: 10px;
}
|
Fonts on the web have been an issue since the very beginning. Very few options are available on each user's computer, and of the options that are available, few are attractive. We are on the verge of experiencing a great change, and font embedding (shown in Figure 6) will let us create brilliant layouts without using heavy images on our pages. Several methods can accomplish this.
Figure 6. Embedding fonts with CSS3
For Internet Explorer, you need access to the .eot file format for the font you want to use. Listing 23 shows how to embed the font once you have the correct font file.
Listing 23. Embedding fonts in Internet Explorer
font-family: yanone;
src: url('../fonts/yanone.eot');
|
For Firefox, Safari, and Chrome, you can embed .ttf or .otf fonts. Listing 24 shows the code to embed these fonts for later use in a web page.
Listing 24. Embedding fonts in Firefox, Safari, and Chrome
font-family: yanone;
src: local('Yanone'), url(../fonts/yanone.ttf) format("truetype");
|
Once you have the font embedded, apply it to an actual HTML element by
creating a class by the name of the font family you used in the @font-face declaration. Listing
25 shows how to use this font in a class and then later apply it
to an HTML element.
Listing 25. Embedding fonts for all browsers and adding a class to assign the font to an element
@font-face {
font-family: yanone;
src: url('../fonts/yanone.eot');
src: local('Yanone'), url(../fonts/yanone.ttf) format("truetype");
}
.yanone {
font-family: yanone, Verdana, Arial, Helvetica, sans-serif;
}
|
HTML5 and CSS3 are bringing great change to the web, but you should exercise caution when using many of their techniques, since a great deal of functionality does not work across browsers. As time progresses, we will see more of this new code being used and supported by the major browsers; this will let us surpass any limitations that require creating workarounds to design web pages and focus more energy on the look and feel of a site.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample HTML5 and CSS3 scripts used in this article | HTML5_CSS3.zip | 120KB | HTTP |
Information about download methods
Learn
- To learn more about HTML5, see the W3C's
specification.
- Discover what's new in CSS3.
- The Web development zone
specializes in articles covering various web-based solutions.
- Stay current with developerWorks' technical events and webcasts.
- Watch developerWorks on-demand demos ranging from product installation
and setup for beginners to advanced functionality for experienced
developers.
Get products and technologies
- Learn more about
html5shim, an HTML5
Internet Explorer-enabling script.
- Download IBM
product evaluation versions or explore
the online trials in the IBM SOA Sandbox and get your hands on
application development tools and middleware products from
DB2®, Lotus®, Rational®,
Tivoli®, and WebSphere®.
Discuss
- Create your My developerWorks profile today and set up a watch list on HTML5 and CSS3. Get connected and stay
connected with developerWorks community.
- Find other developerWorks members interested in web development.
- Share what you know: Join one of our developerWorks groups focused on web
topics.
- Roland Barcia talks about Web 2.0 and middleware in his blog.
- Follow developerWorks' members' shared bookmarks on web topics.
- Get answers quickly: Visit the Web 2.0 Apps forum.
- Get answers quickly: Visit the Ajax forum.

Kris Hadlock has been a contract web developer and designer since 1996. He has worked on projects for companies such as SPIN Magazine, IKEA, United Airlines, JP Morgan Chase, GoDaddy Software, and Fire Mountain Gems. He is the author of Ajax for Web Application Developers (Sams) and The ActionScript Migration Guide (New Riders) as well as a featured columnist and writer for numerous websites and design magazines, including Peachpit.com, InformIT.com, and Practical Web Design magazine. Kris is also the founder of www.studiosedition.com, a web design and software development studio specializing in fusion of form and function.




