Html5 PDF
Html5 PDF
Authors:
Richard Campbell
Daniel Egan
Wallace McClure
Michael Palermo
Dan Wahlin
2 Contents
Contents
About the Authors...............................................................................................1
Introduction........................................................................................................3
Chapter 1: The Past, Present, and Future of HTML5............................................5
Chapter 2: Three of the Most Important Basic Elements in HTML5...................15
Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5..................20
Chapter 4: HTML5 Form Input Enhancements:
Form Validation, CSS3, and JavaScript.............................................................32
Chapter 5: HTML5 Syntax and Semantics: Why They Matter............................38
Chapter 6: Introduction to HTML5 for Mobile App Development....................50
Chapter 7: HTML5 for the ASP.NET Developer.................................................63
Chapter 8: Getting Started Using HTML5 Boilerplate.......................................74
Chapter 9: Start Using HTML5
in Your Web AppsToday!...............................................................................82
Chapter 10: Ease HTML5 Web Development
with jQuery, Knockout, and Modernizr Libraries............................................95
Chapter 11: Build a jQuery
HTML5 Web Application:
The Account at a Glance App............................................................................97
Chapter 12: How to Build a jQuery HTML5 Web Application
with Client-Side Coding................................................................................106
Contents 3
4 Introduction
Introduction
This is an exciting time to be a web developer! Whether you are building public-facing website
applications or creating internal sites for your company, HTML5 has much to offer in providing sorely
needed features that are native to the browser. With growing support among all the major browsers
and with new sites emerging that consistently use it, HTML5 is a must-visit technology for any serious
web developer today.
This eBook, with chapters written by five HTML5 experts, is designed to jump start you into using
HTML5. Not only will you learn the history of HTML and web development, youll find tutorials, boilerplates, and detailed discussions that will help shorten your HTML5 learning curve.
Notice the omission of the <html> and <head> tags. According to the current specs, this is still a valid
document. If these tags are omitted, the browser will still parse the document, and the tags will be
implied. This represents a shift from the strict conformity imposed by the current HTML standard.
Here is another example of how easy it is to adapt to HTML5:
<!DOCTYPE html>
The doctype syntax has been simplified. Compare this to examples of what we have been accustomed to, shown in Figure 2.
Figure 2: Doctype examples
<!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.1//EN
http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd>
<!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.
w3.org/TR/1999/REC-html401-19991224/loose.dtd>
The doctype declaration is required. Although it is clearly easier to type the normal HTML5 doctype,
the deprecated doctypes in Figure 2 are still accepted formats. By the way, the doctype declaration is
not case sensitive, so any of the following are acceptable:
<!doctype html>
<!doctype HTML>
<!DOCTYPE HTML>
Now take a look at Figure 3 to see a more realistic starting point for an HTML5 document.
Figure 3: Simple HTML5 document
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=UTF-8>
<title>Getting Started With HTML5</title>
</head>
<body>
You might find slight differences in this HTML5 document compared to what you are used to. Apart
from the doctype, you might notice the attribute on the <html> tag and the contents of the <meta>
tag. Lets focus first on the <html> tag:
<html lang=en>
The lang=en attribute informs the browser that the contents of this document are in English. This is
much simpler than the following:
<html xmlns=http://www.w3.org/1999/xhtml
lang=en
xml:lang=en>
Look at how much was removed. There is no longer any need to specify the namespace of the document because all elements in HTML5 (unless otherwise noted) belong to the http://www.w3.org/1999/
xhtml namespace. The xml:lang attribute is left over from the XHTML era. So, once again, HTML5
presents a simpler way to do things, but for what it is worth, the older syntax is still acceptable.
Now, how about that <meta> tag? This is how we used to handle it:
<meta http-equiv=Content-Type content=text/html; charset=utf-8>
Of course if you want to use the old style, thats still okay. Its a good practice to make this meta
charset tag the first child of the <head> tag because the specification states that the character
encoding declaration must appear within the first 1024 bytes of the document. Why set the encoding
for the document? Failing to do so can cause security vulnerabilities. Although the encoding can also
be set in the HTTP headers, its still a good practice to declare the encoding in the document.
These subtle differences clearly confirm the WHATWGs commitment to maintaining backward compatibility while allowing changes that simplify or enhance HTML. However, not everything from the
past is preserved in HTML5. For good reason, some tags, such as those in Figure 4, have been given a
proper burial.
The main purpose of semantic elements is to provide context to the data. These tags are not about
how the content looks. Rather, they are more concerned about the substance of the content. You
modify the appearance of these elements through CSS.
The <input> tag in HTML5 supports new attribute types, shown in Figure 6.
With just a few lines of code, you can have a video up and running with interactive controls for
your users to manage! The controls attribute can stand by itself, or you can use controls=controls
to provide the XML-friendly approach. Also, note that within the tags you can provide optional text
that will be displayed if the browser does not support the video tag. As you select your video formats,
remember that not all browsers support the same video types.
If adding video seems easy, HTML5 makes it just as easy to add audio to your site. The markup is
fairly similar:
<audio src=music.mp3 controls>
Sorry, your browser does not support the audio tag.
</audio>
Like the <video> tag, the <audio> tag contains a controls attribute for visual display to manage
volume and positioning of audio, as Figure 8 shows.
To begin your artwork, you need calls in JavaScript are needed. Using the canvas from the preceding
example,Figure 9 shows how to draw a simple blue square.
Figure 9: JavaScript for canvas
<script type=text/javascript>
var art=document.getElementById(myArtwork);
var ctx=art.getContext(2d);
ctx.fillStyle=#FF0000;
ctx.fillRect(0,0,150,75);
</script>
To what degree can the <canvas> tag enhance the user experience? You really must try it yourself
to experience the difference. However, to give you an idea, Figure 10 presents a screen shot of the
game Pirates Love Daisies. This tower-defense game is packed with action, animation, and stimulating sounds. It is so well done that you might find yourself doubting it is a pure HTML5 page.
Web Storage
Web storage represents another nice addition to HTML5. Web storage is a highly anticipated feature
that allows larger amounts of data to be stored locally in the browser without generating a performance hit on round trips. The primary way developers handle local storage today is through cookies.
The disadvantage of cookies is that the data is passed back and forth with every HTTP request or
response.
In HTML5, developers can use one of two options: local or session storage. The difference is that session storage expires when the browser session ends, while local storage has no time limit. This webstorage feature is available through objects in JavaScript. Here is an example of how to store a display
name in local storage:
<script type=text/javascript>
localStorage.DisplayName=Egan-Palermo;
</script>
Note that in the preceding example, DisplayName was made up on the fly. The property name can be
whatever you want it to be.
Header Element
We might as well start at the head of the class: the <header> element. According to the aforementioned W3.org site, The header element represents a group of introductory or navigational aids [It]
is intended to usually contain the sections heading (an h1h6 element or an hgroup element), but this
is not required. The header element can also be used to wrap a sections table of contents, a search
form, or any relevant logos. In other words, the header element contains the stuff developers have
been putting in their <div id=header> tag for many years. Figure 2 shows an example of the header
element.
Figure 2: The HTML5 <header> element
<!doctype html >
<html lang=en>
<head>
<title>This is my sample</title>
<meta charset=utf-8/>
</head>
<body>
<header>
<a href=/><img src=HighFive.png alt=main /></a>
<hgroup>
<h1>HighFive HTML5 Training</h1>
<h2>The one stop shop for all things HTML5</h2>
</hgroup>
</header>
<footer>
</footer>
</body>
</html>
You may notice from the code in Figure 2 that the syntax that starts with <!doctype html> is quite different from what youre used to. The syntax has been simplified and no longer requires the long URL
that we have become accustomed to. Additionally, the tag is not case sensitive. For example, <!DOCTYPE html> is the same as <!DoCtyPe html>. As a matter of fact, you can even leave out the <html>,
<head>, and <body> tags because they are implied in HTML5. However, we do not recommend
leaving them out. You will also notice that the <header> section entails a logical grouping of an image
and <h1> and <h2> tags, all contained within an <hgroup> tag.
Nav Element
Developers frequently want to put menus in the header when menus are used as global resources
across the site. This leads us to the use of the next new element, <nav>. The specification for this
element states, The nav element represents a section of a page that links to other pages or to parts
within the page: a section with navigation links. Of course, this specification identifies the basic use
for the <nav> element, but as we discussed earlier, the real importance of these elements resides in
their broader application. The specification goes on to say, User agents (such as screen readers) that
Of course, this code would normally put hyperlinks inside the <li> elements, but well leave it as is
for simplicitys sake. The specification also helps users determine where not to use this element. For
example, simple links to terms of service or to copyright information in a footer do not typically use
the <nav> element.
Keeping It Simple
Hopefully, by now in this series, its clear why we should care about HTML5. Like most things in programming, simple constructs can have deep underpinnings. Simple elements like <header>, <nav>,
and <footer> can have deeper implications than what initially meets the eye. Understanding why
these elements were created can help us master best practices for their use. We hope you continue
The first link is to the reset.css file. Typically, web designers provide a master or reset type of CSS file
to equalize the defaults across all browsers. In this example, we are using the reset.css file made publicly available by CSS guru Eric Meyer. The next link is to core.css, which contains CSS features up to
version 2.1. The final link is to css3.css (see Figure 3). This file contains features exclusive to CSS3. By
separating CSS into multiple files, we can show how easy it is to distinguish CSS features from one
another. However, all the CSS used in this example could have easily been rolled into one complete
file as well.
Figure 3: Css3.css
@charset utf-8;
@font-face {
font-family
src
font-weight
font-style
}
h1, h2 {
font-family
}
:
:
:
:
TitleFont;
url(michroma.woff) format(woff);
bold;
normal;
: TitleFont;
:
:
:
:
11px;
11px;
11px;
11px;
:
:
:
:
22px;
22px;
22px;
22px;
:
:
:
:
:
0 0 22px 22px;
0 0 22px 22px;
0 0 22px 22px;
0 0 22px 22px;
rgba(0,0,0,0.4);
: table;
: table-cell;
#figureAd {
box-shadow
-webkit-box-shadow
-moz-box-shadow
-o-box-shadow
}
:
:
:
:
11px
11px
11px
11px
#figureAd:hover {
transform
-ms-transform
-webkit-transform
-moz-transform
-o-transform
}
:
:
:
:
:
scale(1.5)
scale(1.5)
scale(1.5)
scale(1.5)
scale(1.5)
.upsideDown:hover {
transform
-ms-transform
11px
11px
11px
11px
11px
11px
11px
11px
#777;
#777;
#777;
#777;
rotate(-10deg);
rotate(-10deg);
rotate(-10deg);
rotate(-10deg);
rotate(-10deg);
: rotate(180deg);
: rotate(180deg);
You may have noticed the <script> tag reference to modernizr.js below the <link> tags in the default.
htm page in Figure 2. Publicly available at www.modernizr.com, the Modernizr JavaScript library lets
us design for the future using HTML5 and CSS3 without sacrificing control over experience in older
browsers. We immediately benefit from this file by simply referencing it.
The CSS3 way of doing things is much easier. Heres how we get a simple two-column layout in the
css3.css file:
#content
{display : table;}
#blogs, #sidebar {display : table-cell;}
The <section> tag that has an ID of content is defined visually as a table. The two child tags with
IDs of blogs and sidebar are defined in the CSS file as table-cell, causing each to render visually as a
column in the table.
:
:
:
:
TitleFont;
url(michroma.woff) format(woff);
bold;
normal;
The @font-face definition first establishes what the friendly name of the font will be by using the
font-family property. In our example, we named the font TitleFont. The src property requires the
URL of the .woff file that contains the desired font. You can find custom .woff selections at sites such
as www.fontsquirrel.com. The other properties define default behaviors for weight and style.
When serving a web page that uses custom fonts, the web server must be configured to understand
the .woff extension and its MIME type. For Microsoft IIS, this can be accomplished by updating the
web.config file, as we have done in Figure 6.
Figure 6: The web.config file
The @font-face definition makes the font available only within the web page. We need to define the
location in which we want the font to be used; we do this by referring to the friendly name elsewhere
in the CSS file. In our example, this is how to use the custom font:
h1, h2 {font-family
: TitleFont;}
In this example, the custom font that has the friendly name of TitleFont will be applied to all <h1>
and <h2> tags in the HTML.
: 11px;}
The border-radius property defines the radius as either a unit value or a percentage value. The
example here eliminates the need to explicitly specify the radius for each corner. So thats it. Well
sort of. To support older browsers or other browsers, vendor-prefixed versions should also be applied.
Here is the example again, this time with support for Mozilla, WebKit, and Opera:
#sidebar section {
border-radius : 11px;
-webkit-border-radius : 11px;
-moz-border-radius : 11px;
-o-border-radius : 11px;
Dont let the duplication bother you too much. If the browser doesnt understand a property, that
property is ignored. And if repetition feels wrong to you, welcome to the world of multiple-browser
support.
Now lets look at an example of applying the rounded effect to just some of the corners. Here, we
want only the bottom-right and bottom-left corners to be rounded:
#banner figcaption
{
:
:
:
:
0
0
0
0
0
0
0
0
22px
22px
22px
22px
22px;
22px;
22px;
22px;
Shadow effects are just as easy to implement. The following example adds a shadow to the <figure>
tag that has an ID of figureAd:
#figureAd {
box-shadow :
-webkit-box-shadow :
-moz-box-shadow :
-o-box-shadow :
}
11px
11px
11px
11px
11px
11px
11px
11px
11px
11px
11px
11px
#777;
#777;
#777;
#777;
Like the border-radius property, vendor prefixes are added to support multiple browsers. The values for
the property indicate the depth of the horizontal shadow, the depth of the vertical shadow, the depth
of the blur effect, and the color of the shadow, in that order. The first two values are required. If negative values are supplied, the shadow goes in the opposite direction.
Color effects are also fairly simple to add. Consider the convention of dimming a photo when it is not
the main attraction. In the past, we had to create a duplicate of the photo and add the dimming effect
with image-editing software. With CSS3, we can define this effect without a modified version of the
original image. Here is an example of applying a dimming effect to the <figcaption> tag associated
with an <img> tag:
#banner figcaption
{
/* other definitions removed for brevity */
background-color : rgba(0,0,0,0.4);
}
The rgba value uses four arguments. The first three define red, green, and blue (RGB) intensities with
a value range of 0 through 255. The remaining value determines opacity, where 1.0 is opaque and
0 is completely transparent. Since the RGB values are all 0 in our example, the color is black, and
the remaining value indicates 40-percent opacity. The effect is a grayish see-through layer above the
image. The <figcaption> tag is absolutely positioned over the <img> in the core.css file. To cover the
entire image with this effect, simply make <figcaption> the same dimensions as the image.
Transformations
In CSS3, transformations take the user experience to the next level. Lets consider just two transformations: scale and rotate. The scale transformation causes any UI element to shrink or grow when a
user hovers over it. Suppose we want a portion of a page to pop out and rotate somewhat when we
hover over it. We can apply the scale transformation to make it grow and the rotate transformation to
scale(1.5)
scale(1.5)
scale(1.5)
scale(1.5)
scale(1.5)
rotate(-10deg);
rotate(-10deg);
rotate(-10deg);
rotate(-10deg);
rotate(-10deg);
The vendor prefixes are all displayed in this example. Did you notice the -ms- prefix? While CSS3
transformations are under development, each browser will continue to have its own implementation.
The first property that contains no prefix is there for future compatibility. Figure 7ashows the UI element before the user hovers the mouse over it; Figure 7bshows the element after hovering over it.
Media Queries
When using CSS, not only do we factor in the various browsersas if that wasnt enough to worry
aboutwe also have to consider various devices, such as mobile phones. With large and small screen
If the screen width is less than 1,000 pixels, we apply new styles accordingly. In our case, we
adjusted margins in the menu, removed the table layout features so the sidebar would fit under the
content, and removed the banner from the display. Figure 9 shows the effect of the media query on
the page.
Obviously, we havent covered all the new features in CSS3, and the features we did cover can be
explored much further. We simply aimed to provide an easy place to start with HTML5 and CSS3.
Most of the new features can save you needless grunt work. With just one line of code in CSS, you
can sometimes do what used to take a lot of work and many lines of code. We are confident that
once you start down the path of creating web sites with HTML5 and CSS3, you will never go back to
anything else!
32 Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript
By Michael Palermo
Can you imagine what the web would be like if it were truly read-only? What if there were no way
for a user to interact with a site by providing personal data? With no way to input data, the Internet
would be full of brochure-ware sites that could not engage in any real business exchanges. The
value of the Internet would be insignificant compared with what it is today.
So it goes without saying that a required factor for many successful websites is the ability to acquire
data from a user. And because user interaction plays such a key role in the overall web experience,
it isnt surprising that among the many improvements found in HTML5 are feature enhancements to
form input. In this article, I will introduce these new form features, exploring some of the new elements and attributes, how to apply styles, and new ways to control validation in script. Rather than try
to cover everything that is new, instead I will focus on some practical aspects of HTML5 form development that you can start using today.
Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript 33
<label for=phone>Phone</label>
<input id=phone name=phone type=text />
<input id=submit name=submit type=submit
value=Send Data />
</form>
34 Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript
A consideration of these typical scenarios will help us to appreciate the addition of the new HTML5
form input features. In the remainder of this article, I will discuss the advantages of whats new
while walking through the process of upgrading the simple HTML form one feature at a time.
Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript 35
Although other modern browsers also support many of the new form features, I wanted to keep the
focus primarily on the what and how, not on the where. As browsers (and standards) continue to
evolve, we will have plenty of opportunities to learn about varying implementations.
What about browsers that do not support the new HTML5 form input features? Depending on what
new feature is being introduced, there is a different impact and possible way to manage. For example,
consider the following type-attribute changes to these input elements in the simple HTML form:
<input id=email name=email type=email />
<input id=site name=site type=url />
<input id=phone name=phone type=tel />
What will happen when a browser that does not support the new type values renders these inputs?
The browser will render these the same as type=text. In other words, the form will behave just as it
did prior to the changes.
Yet what will happen if the browser supports the new features? Using the same data input, notice how
the browser responds to the click of the Send Data button in Figure 5.
36 Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript
Wouldnt it be nice to inform the user what the valid format for any of the text-based inputs is? That is
the role of theplaceholderattribute. It acts as a watermark for the input, giving the user direction as to
how to enter the data. We will update the three new input types so that they all have placeholders:
<input id=email name=email type=email
[email protected]/>
<input id=site name=site type=url
placeholder=http://www.yoursite.com />
<input id=phone name=phone type=tel
placeholder=(###) ###-#### pattern=\(\d\d\d\) \d\d\d\-\d\d\d\d />
Figure 6 shows what the rendered form looks like after weve added the placeholder attribute.
However, many developers probably feel uncomfortable seeing an attribute without a value. Therefore, this is also acceptable:
<input id=name name=name type=text required=required />
And because this is the first input in the form, we can enhance the user experience by giving it immediate focus with the newautofocusattribute. Unlike therequiredattribute,autofocusshould be given
a value of true or false, as in the following updated name input:
<input id=name name=name type=text required=required
autofocus=true />
Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript 37
Now when the user pulls up the form and submits it without any data entry, the resulting impact on
the displayed form is what is shown in Figure 7.
When states are mixed with the :focus or :not(focus) qualifiers, multiple dimensions of styles emerge.
To demonstrate, look at the CSS markup in Figure 8. Required data will have a faint yellow background, valid data will be green, and invalid data will be red. When the styles are applied to the
page, the result is seen as in Figure 9.
Figure 8: CSS definitions for new HTML5 form inputs
input.data:required
{
background-color: rgba(255, 255, 0, 0.04);
38 Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript
}
input.data:not(:focus):valid
{
Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript 35
and attributes, it represents the core validation behavior that you need to have greater control over the
process.
Returning to the issue of how browsers provide error messages, what if we wanted to create our own
messages? For example, what if we wanted the browser to displayYour full name is required!instead
of the browsers default input-validation message? The code inFigure 11provides a solution. After you
include this JavaScript module in the page, the code will hook into the validation process and allow
the developer to control the error messages, as shown in Figure 12.
Figure 11: JavaScript functions for custom validation
(function() {
// helper functions
function id(elementId) {
return document.getElementById(elementId);
}
function addEvent(src, eventName, func) {
36 Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript
src.addEventListener(eventName, func, false);
}
// custom validation
function validate(evt) {
// reset any existing messages
this.setCustomValidity();
if (!this.validity.valid) {
// if custom message exists, use it
if (this.errMessage) {
this.setCustomValidity(this.errMessage);
}
}
}
// initialize validation for input
function initValidate(src, errMessage) {
// if errMessage provided, set to input
if (errMessage) { src.errMessage = errMessage; }
addEvent(src, change, validate);
addEvent(src, invalid, validate);
}
// initialize javascipt module
function initialize() {
initValidate(id(name), Your full name is required!);
}
// wire up to loading of document
if(document.addEventListener) {
document.addEventListener(DOMContentLoaded, initialize, false);
} else {
window.attachEvent(onload,initialize);
}
})();
Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript 37
In Chapter 2 we introduced the concept of semantic tags by considering the <header>, <nav>, and
<footer> elements. This article extends the discussion by going into more depth about the overall
structure of an HTML5 document and the key reasons for using any of the new semantic elements.
The content in the <title> element in callout A contains the following syntax:
This is a placeholder for the title content, which will be provided by the requested page. We'll see an
example of this shortly.
For now, let's examine the markup between the <body> tags of _SiteLayout.cshtml, shown in Figure 4.
Callouts A and B show code changed from the default content. This is a <div>-centric document typical of websites today. However, the only way to understand the purpose of a <div> in this example
is by inference of the id attribute. Found in this file are id values such as page, header, login, main,
content, and footer.
Figure 4: Markup inside <body> tags of _SiteLayout.shtml
<div id="page">
<div id="header">
<p class="site-title">HTML5 Demo Site</p>
<div id="login">@if (WebSecurity.IsAuthenticated)
{
<p>Welcome
<a href="@Href("~/Account/ChangePassword")"
title="Change password">@WebSecurity.CurrentUserName</a>!
<a href="@Href("~/Account/Logout")">Logout</a>
</p>
} else {
<ul>
<li><a href="@Href("~/Account/Register")">Register</a></li>
<li><a href="@Href("~/Account/Login")">Login</a></li>
</ul>
}
</div>
<ul id="menu">
<li><a href="@Href("~/")">Home</a></li>
<li><a href="@Href("~/About")">About</a></li>
</ul>
</div>
<div id="main">
<div id="content">
<h1>@Page.Title</h1>
<h2>@Page.Subtitle</h2>
@RenderBody()
</div>
<div id="footer">© @DateTime.Now.Year, Don't steal me</div>
</div>
</div>
Note the <div> with an id of "content" in Figure 4, which contains the following syntax:
<h1>@Page.Title</h1>
These lines will render content from the requested page. For example, if the requested page is default.
cshtml, the contents of that file will be rendered where the @RenderBody() syntax is located. Values
for @Page.Title and @Page.Subtitle will be assigned in a code block in the requested page. So for
completeness, we will use default.cshtml as the requested file. Figure 5 shows the adjusted markup of
that file.
Figure 5: Markup of default.cshtml
@{
Layout = "~/_SiteLayout.cshtml";
Page.Title = "Semantics Demonstrated!";
Page.Subtitle = "The Secret is in the Source...";
}
<div id="logo">
<img src="http://bit.ly/html5semantics_logo"
width="133" height="64"
alt="HTML5 Powered with Semantics"
title="HTML5 Powered with Semantics" />
<span>HTML5 Semantics</span>
</div>
<p>
A list of semantic elements
</p>
<ul>
<li>article</li>
<li>aside</li>
<li>figure</li>
<li>figcaption</li>
<li>footer</li>
<li>header</li>
<li>hgroup</li>
<li>nav</li>
<li>mark</li>
<li>section</li>
<li>time</li>
</ul>
<div id="sidenote">
<h1>
<p>
What does semantic mean? A relevant definition is:
<span class="definition">to show, indicate by sign</mark>
In HTML5, the "sign" is the element.
</p>
</div>
As noted earlier, _SiteLayout.cshtml (see Figure 3) is structured primarily using <div> elements. And
although doing so is now commonplace (and is perfectly legal in HTML5), we have opportunities to
provide more meaning to our content by making minor modifications to the HTML source. But before
we do that, we have to ask whether or not a <div> is truly the right choice for grouping content.
What about the first <div> in our example:
<div id="page"> ... </div>
What purpose does the above <div> serve? As the only direct child element of body, it appears to be
a container for the entire page. Why is this here? The following definition in the site.css file gives the
answer:
This style definition is applied to <div> to provide value to the presented page. Because the sole
purpose for this <div> is to support presentation, it does not need to be changed-nor does it have
any semantic value.
Now let's consider the next <div> (displaying what is relevant):
<div id="header">
<p class="site-title">HTML5 Demo Site</p>
...
</div>
With HTML5, semantic elements can replace the <div> and <p> tags to provide more meaning.
But wait-who really cares whether or not our data has more meaning? The answer might lie in the
rephrasing of the question:Whatreally cares whether or not our data has more meaning? How will
your page be parsed by search engines? What will the logical outline be according to the browser?
Fortunately, a number of online resources are available to help provide insight about how HTML
pages will appear in "outline" form. For our example, I will use gsnedders.html5.org/outliner. When
we feed the outliner site with the rendered source of the site with no modifications, the site should
output an outline similar to the one that Figure 8 shows.
Introducing Semantics
Returning to our <div id="header">, we will now change it to the following:
<header id="header">
<h1 class="site-title">HTML5 Demo Site</h1>
...
</header>
The <header> element contains content that is page- or site-wide, and usually includes navigation
(something we will visit shortly). In the example above, an <h1> tag is used inside the <header> tag
to provide the heading title. In the past, it was considered proper form for only one <h1> element to
exist in the page. That is not true for HTML5 documents. The context of its placement is what gives it
weight.
Was it necessary to keep the id and class attributes in the above changes? No. However, removing
the attributes could affect style definitions in the site.css file. To demonstrate a smooth transition, we
elected to keep all id and class values in their new semantic element homes. If you decide to remove
them in your sites, you should modify dependent CSS files accordingly.
Let's revisit the following markup in the _SiteLayout.cshtml file:
<div id="content">
<h1>@Page.Title</h1>
<h2>@Page.Subtitle</h2>
@RenderBody()
</div>
The primary "content" of this page can really be viewed as an article with a title, subtitle, and body of
information. Thus, here is how it looks with semantic markup:
<article id="content">
<hgroup>
<h1>@Page.Title</h1>
<h2>@Page.Subtitle</h2>
</hgroup>
@RenderBody()
</article>
The <div> was replaced with an <article> element. The <h1> and <h2> elements are now grouped
in an <hgroup> element, so that the <h2> tag does not introduce a new section into the outline. In
fact, if we run the page through the outliner site now, we will see the improvements shown in
Figure 9: Example HTML5 source outline after first set of code modifications
The source of the final line in the outline is the last <div> in default.cshtml (see Figure 5). Since this
data is considered "side note" data, and is not regarded as the main content of the article, we can reengineer it to use semantics, as follows:
<aside id="sidenote">
<h1>What does semantic mean?</h1>
<p>
A relevant definition is:
<mark class="definition">to show, indicate by sign</mark>
In HTML5, the "sign" is the element.
</p>
</aside>
Once again, the <div> has been replaced-this time with the <aside> element. Although the <aside>
contains an <h1> element, it will be regarded with less importance by the search-engine parser
because of its ambient container. The <span> was replaced with a more appropriate choice, the
<mark> element. As the name implies, it represents text to be marked or highlighted. After one more
run-through with the outliner after all the code changes, we see a proper indentation of the outline,
shown in Figure 10.
Figure 10: Example HTML5 source outline after second set of code modifications
More Semantics
There are other areas in the document that are easy to identify for semantic markup. For example, in
the _SiteLayout.cshtml file (see Figure 3), the final <div> on that page is for the footer. We can replace
it as follows:
<footer id="footer">
©
<time datetime="@DateTime.Now.ToString("yyyy-MM-dd")">
@DateTime.Now.Year
</time>, Don't steal me...
</footer>
Note the insertion of the <time> element. It simply provides a stronger context for any date or time
provided in the HTML markup.
How about the links to other pages in the site? The following code:
<ul id="menu">
<li><a href="@Href("~/")">Home</a></li>
<li><a href="@Href("~/About")">About</a></li>
</ul>
can be changed to this:
<nav id="menu">
<h1>Site Navigation</h1>
<li><a href="@Href("~/")">Home</a></li>
<li><a href="@Href("~/About")">About</a></li>
</nav>
Because the links in this code are regarded as the primary navigation within our site, it is appropriate
to use the <nav> element in this case. But why did an <h1> tag sneak in? The <nav> element is factored in the outlining of the document. An <h1> element provides the semantic meaning, though the
site.css file prevents it from being viewed.
What about the HTML5 logo in default.cshtml (Figure 5)? It can be transformed to be semantic, as
follows:
<figure id="logo">
<img src="http://bit.ly/html5semantics_logo"
width="133" height="64"
alt="HTML5 Powered with Semantics"
title="HTML5 Powered with Semantics" />
<figcaption>HTML5 Semantics</figcaption>
</figure>
Not only was the <div> replaced with <figure>, the span was replaced with a more suitable option,
the <figcaption> element.
Figure 11: Viewing an HTML5 document's semantic elements using the HTML5 Semantic Notepad
Despite the small amount of content in the demo article, there is an appropriate use for the <section>
element in it. In the default.cshtml file, we will change the list of semantic elements to be in its own
"section," as shown in Figure 12.
Figure 12: Adding a <section> element to an HTML5 document
<section>
<h1>A list of semantic elements</h1>
<ul>
Because this content can be logically grouped together, it makes sense to put it in a <section>. This is
especially the case when you have reason to provide a heading for the content. Other uses for a <section> could be to indicate sidebar content with its own heading or a grouping of links with its own
heading.
When we run our example HTML5 one last time through the outliner site, we see a rich HTML5
outline generated as a result of the correct usage of semantic elements in the document, as shown in
Figure 13.
Figure 13: Example HTML5 source outline after final set of code modifications
http://www.devproconnections.com/content/content/141262/141262_ExampleApp.zip
HTML5 is the umbrella term for the next major evolution of markup, JavaScript, and Cascading Style
Sheets (CSS) for web applications. HTML5 is becoming an ever-more important mobile development
technology -- especially in light of Adobe's recent announcement that it's ceasing development on
Flash Player for mobile browsers and increasing its investments in HTML5. In this article, I intend to
provide a comprehensive overview of HTML5 with an emphasis on features oriented toward mobile
development. We'll dive into some specific examples of HTML5 features and focus specifically on
what is available with mobile devices. I will focus on what developers can do today as opposed to
what is part of the specific set of standards. I'll also mention where a product may have a slightly different outcome than expected.
Markup
HTML5 introduces many new tags and attributes. In this section, we'll take a look at the ones you as
a developer will likely need to use immediately.
HTML5 page. First off, an HTML5 page is much easier to set up than a web page in earlier HTML
versions. Previous versions of HTML and XHTML had very complicated XML namespace support that
average developers were confused by and honestly didn't pay much attention to. HTML5 has a much
simpler page definition and will be simpler for developers to get started with.
Figure 1: Sample HTML5 page
<!DOCTYPE html>
<html @Page["CacheManifestFile"]>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-compatible" content="IE=edge,chrome=1" />
Let's look at an HTML5 template, shown in Figure 1, which I created for my HTML5 samples (available for download with the online article; see the top of page for the download button). There are a
few items to note in the sample code:
The <DOCTYPE/> tag is much simpler than we formerly saw in HTML. The tag instructs the browser
to run in standards-compliant mode.
The <meta/> tag with the http-equiv attribute instructs the browser to use the most recent version
of the HTML engine in the browser. In addition, if the user has the Google Chrome Frame plug-in
installed, the Chrome Frame engine is used in Internet Explorer (IE). (See the sidebar "Author's Notes"
at the end of this article for more information about Chrome Frame.)
The code download includes a set of jQuery and jQuery Mobile CSS and JavaScript libraries.
Although use of these libraries is clearly not a strict requirement for HTML5, they will be used to hook
into the HTML5 page and provide features that will make development easier.
As you can see, the <source/> tag indicates that HTML5 supports the .mp3 file type. Various file types
can be specified in the <source/> tag (e.g., .ogg).
HTML5's <video/> tag provides video support. There is a major difference between audio and video
in the browser world. With audio, MP3 has widespread support among the various browsers that
developers will encounter. There's no equivalent "default" video format in the marketplace. Figure 2
shows a short example that uses the <video/> tag.
Figure 2: Using HTML5's <video/> tag
<video controls="controls" onclick="this.play();"
poster="@Href("~")images/PlayVideo.png">
<source src="@Href("~")Content/HTML5.mp4" preload="none" />
<source src="@Href("~")Content/HTML5.webm" preload="none" />
<source src="@Href("~")Content/HTML5.ogv" preload="none" />
<source src="@Href("~")Content/HTML5.m4v" preload="none" />
<source src="@Href("~")Content/HTML5264.mp4" preload="none" />
Your browser does not support html5 video. Try some flash.
</video>
mimeType="video/mp4"
mimeType="video/ogg"
mimeType="video/web"
mimeType="video/mp4"
/>
/>
/>
/>
Both the <audio/> and <video/> tags and the browsers that support them provide support for JavaScript methods and events. Some of these methods and events can be used to start playing the multimedia, pause the multimedia, handle the multimedia finishing, and initiate numerous other changes
and events.
Input tags and attributes. We've had the same set of input tags in HTML for many years. These include
<input/>, <select/>, <form/>, and others. These tags have served us well. We've learned over the past
few years that there are numerous user input scenarios that we can optimize. For example, how many
times have you used a text field to allow the user to input a phone number? You may have had to use
some logic to limit the input to numbers or another similar form. It would be nice if we had a tag that
was optimized for a phone number. HTML5 provides this along with other new input types. The following examples demonstrate how to use HTML5 input tags:
<input id="phone" name="phone" type="tel" placeholder="Phone"/>
<input id="email" name="email" type="email" placeholder="Email"
autocapitalize="off" />
For a desktop web browser, this may not be a big deal, but for a mobile user, the tel and email input
types can be a godsend. The tel type is used as a hint to the browser to open a keyboard that is optimized for phone input, like the one shown in Figure 4. This keyboard will handle primarily numeric
input. The email type will result in a keyboard being opened that is optimized for inputting an email
address.
Figure 4: Keyboard for the input type tel in the Android browser running in the emulator
I'm sure that developers are now thinking, "This is great, but what happens when I run this on IE8 or
another browser that doesn't support these new input types?" Thankfully, when a browser, such as an
old version of IE or Firefox, encounters an input type that it does not understand, the browser will display the input tag as a text field. This allows a developer to start using these new input types and still
have backward compatibility with existing browsers. Note that I've covered only a few of the input
types. HTML5 provides more input types to handle dates, numbers, and other types of input data.
In addition to new input types, numerous new attributes are available. Two new attributes worth mentioning here are placeholder and autocomplete attributes. The placeholder attribute allows for text to
be placed within a TextField class as a watermark, as shown in Figure 5.
There are more new tags and attributes in the HTML5 specification. You can find a larger listing of the
tags here.
JavaScript
HTML5 includes a number of new JavaScript methods and JavaScript support for HTML5 tags and
features. There are a number of new methods for supporting <audio/>, <video/>, and other supported
features. Let's look at some of them.
Geolocation. Although geolocation support is not an official part of the HTML5 specification, it's hard
to overlook it. For the purposes of this article, we'll consider it a part of HTML5. With geolocation, it's
possible for a browser to request the location information from the underlying operating system. This
occurs by performing the following steps:
1. A browser check is performed to verify that the browser supports geolocation. In the example in
Figure 6, the check is performed using the Modernizr library.
2. The getCurrentPosition method is called with the three parameters. The first parameter is required,
and the second two are optional.
a. The first parameter is a callback on success. This callback will be called when the geolocation
value is determined.
b. The second parameter is a callback on error. This callback method happens when there is an
error determining the user location.
c. The third parameter is options that can be passed in. In this example, enableHighAccuracy is
turned on.
Figure 7 displays the results of the code in Figure 6, with a map showing the user's location.
You can find a complete listing of the features of the <canvas/> tag here. Also see Dan Wahlin's
articles "Using the HTML5 Canvas Tag" and "HTML5 Tutorial: Build a Chart with JavaScript and the
HTML5 Canvas."
Web SQL. Storing data is a problematic issue with web applications. Web developers are familiar
with cookies, a type of persistent data storage. Over time, the need for data storage support for web
apps has grown. To solve some of these problems, the localStorage and sessionStorage attributes have
been added and accepted into web browsers. Unfortunately, these attributes don't provide the more
complex types of storage support that developers need. To address this need, the Web SQL standard
was created. Web SQL allows for more data to be stored in a relational format that many developers
are familiar with.
Unfortunately, Web SQL has run afoul of the standards process. Although the Web SQL standard
exists, it is not being enhanced further. For the desktop, this is an issue; however, Web SQL has been
supported in Android and iPhone, so it has tremendous support in the mobile environment.
Let's look at a short JavaScript example, shown in Figure 10, which demonstrates using Web SQL,
with the results of the code shown in Figure 11.
City)');
[1, "Las Ve[2, "Knox[3, "Atlanta"]);
[4, "Houston"]);
[5, "Washington
Further Explorations
One final note: As you develop applications that use HTML5, you may also want to make use of
frameworks. The examples here are based on the jQuery Mobile framework. I have used it to due to
the popularity of jQuery among ASP.NET developers. However, jQuery Mobile is by no means the
only framework that you can use. Some of the others are jQTouch, Sencha touch, iWebKit, Wink,
and others. I hope that you have enjoyed this introduction to HTML5 and will use this article as a
jumping-off point in your explorations of these and other HTML5-related technologies and tools.
62 [sidebar]
[sidebar]
Author's Notes
Here are a few considerations to be aware of as you're reading this article:
As a developer, I have many "interesting" things installed on my system. One of those things is the
Google Chrome Frame, which is a Google-written plug-in for Internet Explorer (IE). Google Chrome
Frame is not the Google Chrome browser for IE. Rather, it is a plug-in that brings some HTML5 features to IE 6, 7, and 8. This was on my system before I installed IE 9 -- thus, you may experience some
differences in output when you run the code samples.
There are various third-party browsers for Android. Some support the HTML5 features mentioned
in the article, some do not. For example, Firefox on Android does not support Web SQL, whereas the
built-in Android browser does. Because of these variations, I highly recommend using the Modernizr
framework to test a browser for feature support.
Because of the number of browsers and combinations, it's important to use feature detection in an
application as opposed to browser detection.
The HTML5 samples written with this article use Razor and ASP.NET Web Pages. The key pieces are
in the individual pages. (For more information on these topics, see Brian Mains' article "Using ASP.
NET Web Pages with the Razor View Engine."
The jQuery Mobile libraries used are based are the daily build of jQuery Mobile. This can result in
breakage one day and everything working properly on another day.
A Peek at HTML5
Let's take a peek at a simple HTML5 web page and make some key observations about the code.
Figure 1 shows some sample source code.
Figure 1: Sample HTML5 source code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-compatible" content="IE=edge,chrome=1" />
<title>About My HTML5 Site</title>
Notice that the doctype tag, which tells a browser which version of HTML to use, is now much simpler. In HTML5, there is only one doctype tag. The X-UA-Compatible meta tag tells the browser to
use the most recent engine available. My system has the Google Chrome frame plug-in installed, so
this information is included, as well as the instruction to use the most recent version of the Internet
Explorer (IE) engine. Finally, the page is logically divided by header, content, and footer tags. These
tags instruct a browser to separate the content visually. This instruction is particularly important for a
mobile web browser.
Browsers Galore
Currently, there is no single dominant browser. We've got IE, Firefox, Chrome, Safari, and Opera for
the desktop. Add to those the many mobile device browsers such as Safari, the Android browser, and
the mobile IE for Windows Phone 7, along with the various versions of each browser. Developers are
presented with a vast and complex array of scenarios to code for. In this vein, you may be familiar
with the following JavaScript code:
If ( navigator.useragent.indexOf(.) > -1)
{
// do something...
This code determines whether the browser is of a specific type. It then responds accordinglyfor
example, by redirecting the browser to a page optimized for that browser.
Similar functionality exists on the server. The ASP.NET developer can use the Request.Browser serverside object. Some of the properties of this object that you may find useful include the following:
Request.Browser.IsMobileDevice
Request.Browser.MobileDeviceManufacturer
Native IE9
At the MIX11 conference, Microsoft made a lot of predictable noise in support of IE because of its
"native" status. Terms like native HTML were bandied about. Add to that an early June 2011 demo
of Windows 8 with HTML and JavaScript, and there has been some understandable confusion in the
marketplace. With all these terms and ideas being tossed around, what's a developer to do? Microsoft will have its BUILD conference in September, so hopefully we'll know more then. In the mean
time, there are a few things that we do know about IE9 regarding its optimizations and hardware
acceleration.
First, we know that the JavaScript engine has been rewritten to support multiple processor cores. Specifically, a background compilation takes JavaScript and converts it into machine code that runs faster
on a given system. Secondly, the machine code that the JavaScript engine produces takes advantage
of the most recent and optimized machine commands. Finally, we know that the HTML, Scalable
Vector Graphics (SVG), CSS, audio, and video support have been reconfigured for hardware acceleration. Microsoft may have added these features to support modern hardware capabilities such as
graphics processing units (GPUs), multiple cores, and other new developments. For example, the
<canvas> tag will attain a big boost in performance when it is used in IE9. Overall, it appears that the
folks at Microsoft are promoting their browser as the best platform because there are fewer operating
system layers to go through when you use IE in a Windows environment.
Figure 3: The default ASP.NET Web Forms project displayed in the Android 2.3 Emulator browser
Web Forms
ASP.NET Web Forms is a very popular development framework. The problem with Web Forms is that
some of its standard features create confusion. The most problematic features in HTML5 and mobile
spaces are ViewState, ClientIDs, and MasterPages. We'll walk through ways to provide users with a
more optimal solution to the problems encountered when using these features.
ViewState. ASP.NET developers are used to working with ViewState, the feature that makes Web
Forms work. However, ViewState increases the size of the web page. For example, if you bind a set of
objects to a grid, the size of the page increases dramatically. While the size of the page is not necessarily a big deal for applications that are running over a fairly reliable network, increased page size
greatly increases the risk of an error when the page is transmitted over wireless 3G and 4G networks.
To work around this issue, you have two options.
First, you can turn off ViewState unless it's needed by a specific control on a page. When you turn off
ViewState, it is minimized unless it's absolutely needed, as determined by a developer. However, a
page may still be too large because ViewState is stored on the client web page. In this scenario, ViewState can be turned off at the container, page, application, or server level. Turning it off at these levels
eliminates the ViewState payload unless it's absolutely necessary for a control.
ASP.NET 4 introduces a feature that lets you turn off ViewState at a higher level in the hierarchy, then
turn it on as necessary. Specifically, ViewState can be modified by the ViewStateMode attribute in an
ASP.NET control. In the examples in Figure 4 and Figure 5, a grid of data is displayed to the user. The
GridView doesn't require many of the more complicated features typically associated with HTML5,
so turning off ViewState has no effect on the application or the user. Note that the ViewState mode
is turned off within the Content2 container. Figure 4 shows the code for the content view. Figure 5
shows the output of the code in Figure 4.
Figure 4: Code for the content view
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"
ViewStateMode="Disabled">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></
script>
Unfortunately, developers are not the only folks who work on a project. Designers are also involved,
and they may not be familiar with the functionality behind control IDs. Therefore, a new feature was
introduced in ASP.NET 4 to grant programmers complete control over the client IDs that are generated. This feature is controlled by the ClientIDMode attribute. The values of particular interest for this
attribute are Static and Predictable. The Static attribute makes sure that the client ID that is generated
remains the same as the server ID. The Predictable attribute is used in conjunction with the databound controls and the Static value to generate repeatable client IDs in a grid.
MasterPages. Although not necessarily a requirement for Web Forms developers, MasterPages is a
great tool for sharing display layout among pages. I don't recommend that you try to use the same
general layout for both a desktop web application and a mobile web application. Instead, it makes
sense to create a master page optimized for mobile devices and to continue using this design and
layout technique, although MasterPages will certainly be different because of the difference in the
layout capabilities of a mobile device and a desktop web browser.
HTML5 Validation
In the Visual Studio 2010 SP1 release, the April 2011 ASP.NET MVC 3 Tools update, and the June
2011 release of the Visual Studio Web Standards update, Microsoft not only updated its MVC tools,
but it also added support for HTML5, as illustrated in Figures 6A and 6B. Developers now get support
for HTML5, CSS3, and the JavaScript objects that support the new features. With CSS3 support, even
the IE, Mozilla, and Safari extensions are supported.
Figure 6A: HTML5 validation setting and IntelliSense support for HTML5 tags in Visual Studio 2010 SP1
Figure 6b: CSS3 and IntelliSense support in Visual Studio 2010 SP1
ASP.NET MVC
In pages and applications based on the MVC design pattern, the presentation logic is decoupled from
the underlying application logic. If an application needs to present different views of the same data to
a desktop and a mobile client web client, it is possible to reuse the underlying models and controllers
and merely swap the views as necessary. I think this is a huge win for web developers who are using
the ASP.NET MVC framework.
With the recent MVC3 Tools update, the ASP.NET team has added the ability to use HTML5 by
default. You can do so by selecting the Use HTML5 semantic markup check box, as shown in Figure
9.
Dive in to HTML5
I hope this introduction to making applications work with HTML5 has been helpful. HTML5 already
has a lot of support in ASP.NET and Visual Studio, and many more features and capabilities are
coming down the pipeline. I hope you are now as excited as I am about the new features that are
possible with HTML5. They're definitely making ASP.NET fun again for me, and I think you'll enjoy
them, too.
CSS Support
Two CSS files are included out of the box: the main CSS file used by the site, named style.css, and a
starter script for hand-held devices, named handheld.css. The style.css file includes several different
tips, tricks, and best practices that can be used to handle rendering HTML across multiple browsers
(including IE6). It adds in some clever features, such as hiding content from a page and ensuring the
content doesnt take up any space while still making it available to screen readers. Figure 4 shows an
example of a CSS class named visuallyhidden that performs the screen reader trick.
Figure 4: Screen reader trick employed by HTML5 Boilerplate
/* Hide only visually, but have it available for screenreaders: by Jon Neal.
www.webaim.org/techniques/css/invisiblecontent/ & j.mp/visuallyhidden */
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px;
overflow: hidden; padding: 0; position: absolute; width: 1px; }
/* Extends the .visuallyhidden class to allow the element to be focusable when
navigated to via the keyboard: drupal.org/node/897638 */
.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow:
visible; position: static; width: auto; }
The style.css file also includes the popular clearfix solution that can be used to prevent margins from
collapsing on child elements when the children are floated. If youve ever written HTML and CSS
where you floated children left or right, then had to add a final child with clear:both in the style
to make things look right, youll find that this fix greatly simplifies the process since you can simply
apply the clearfix class, as the code in Figure 5 shows.
Figure 5: The clearfix used to handle floating children in HTML pages
/* The Magnificent Clearfix: Updated to prevent margin-collapsing on child elements. j.mp/bestclearfix */
.clearfix:before, .clearfix:after { content: \0020; display:
block; height: 0; overflow: hidden; }
.clearfix:after { clear: both; }
/* Fix clearfix: blueprintcss.lighthouseapp.com/projects/15318/tickets/5-extramargin-padding-bottom-of-page */
.clearfix { zoom: 1; }
Print styles are also included to simplify the process of removing backgrounds, handling links, printing
table rows, handling images, and more, as shown in Figure 6.
Figure 6: Using HTML5 Boilerplates support for printing pages
/**
* Print styles.
Moving into the js folder in the project, youll find jQuery, IE6 .png support, and Modernizer scripts
included in the js/libs folder. Custom scripts can go in the scripts.js file, and plug-in scripts can go
in plugins.js. Any custom libraries used in the site can go in the mylibs folder. Keep in mind that the
folders are only a recommended folder structure, and as the HTML5 Boilerplate site likes to say, all
the code is delete-key friendly, so feel free to reorganize things to fit your needs.
First, youll note that the standard HTML5 doctype declaration is defined. I cant tell you how happy
it makes me to have this simple definition since the different XHTML doctype options were hard to
remember. Immediately under the doctype youll notice the inclusion of several conditional state-
At this point, you may wonder how the no-js class gets removed from the <html> element when a
browser does support JavaScript. After all, if the browser supports JavaScript, it wouldnt make much
sense to have a no-js class defined. To handle this situation, the HTML5 Boilerplate code adds a reference to the Modernizr script within the head section of index.html:
<script src=js/libs/modernizr-1.7.min.js></script>
By default, Modernizr will locate the <html> element and change no-js to js if JavaScript is supported
by the browser. Figures 7 and 8 show an example of how Modernizr modifies the <html> element;
the example in Figure 7 uses the IE9 developer tools (press F12 when viewing a site in IE9 to get to
the developer tools), and the Figure 8 example uses the Chrome developer tools (Ctrl+Shift+I).
Figure 7: Viewing the <html> element using the IE9 developer tools
Figure 8: Viewing the <html> element using the Chrome developer tools
HTML5 Boilerplates index.html page includes several other interesting features, such as the meta tags
shown in Figure 9.
The first meta tag sets the character set to utf-8 and is a shorthand version of what was used previously in web pages:
<meta http-equiv=Content-Type content=text/html;charset=utf-8 >
At first glance, setting the character set may seem trivial and unimportant, but it can actually stop
some script attacks that rely on utf-7, so its recommended that you define it in your pages. The
second meta tag shown in Figure 9 is used to force Internet Explorer to use its most modern rendering
engine. This comes into play with IE8 and IE9 since they have compatibility modes that a user can
select in the address bar and ensures that Internet Explorer compatibility mode rendering isnt used
(even if the user selected it). Although this second meta tag doesnt pass the latest W3C validation test,
its good to have to prevent IE8/IE9 browsers from reverting back to IE7 mode due to the user enabling
compatibility mode.
Moving down further in the <head> element within index.html, youll see that Googles Content
Delivery Network (CDN) is used to load jQuery:
<script
src=//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js></script>
This provides several benefits related to caching and location. A user visiting a site that references the
Google CDN URL for jQuery will have the script cached in their browser. If they then visit your site
that references the same CDN script file, the cached version will be used, resulting in faster page load
times. Also, Googles CDN servers (note that Microsoft also provides a CDN for jQuery) are located
throughout the world, so when the jQuery script gets loaded for the first time, a server close to the
users location will normally be hit.
Having a reference to the CDN version of jQuery is nice, but its always good to have a fallback in
case the CDN is inaccessible for any reason. HTML5 Boilerplate uses a trick I like to use as well to
embed a local copy of jQuery if the CDN version cant be loaded. It does so by checking for the existence of the window.jQuery object. If the object isnt found, then the CDN script wasnt loaded successfully and a local version of the script is loaded instead:
<script>window.jQuery || document.write(<script src=js/libs/jquery-1.5.1.min.
js>\x3C/script>)</script>
Another key item added into index.html is a reference to the Google Analytics script for tracking page
hits and other details. If you have a Google Analytics account, you can update your sites ID in the
provided script:
Testing Features
In addition to the HTML, CSS, and JavaScript features added by HTML5 Boilerplate, support for
QUnit is also included out of the box. QUnit is a JavaScript test library used to test the Query project
code but can also be used to test JavaScript code that you write. Within the project created by HTML5
Boilerplate, youll find a folder named test that contains the qunit.js and associated CSS file as well as
a sample test HTML page and test script. The test script provides a few basic examples of using QUnit
to perform assertions and test logging functionality available in the plugins.js file included with the
project (see Figure 10). A complete discussion of QUnit is outside the scope of this article, but you
can read more about it on the jQuery QUnit page.
Figure 10: QUnit test script provided by HTML5 Boilerplate
module(example tests);
test(HTML5 Boilerplate is sweet,function(){
expect(1);
equals(boilerplate.replace(boilerplate,sweet),sweet,
Yes. HTML5 Boilerplate is, in fact, sweet);
})
// these test things from plugins.js
test(Environment is good,function(){
expect(3);
ok( !!window.log, log function present);
var history = log.history && log.history.length || 0;
log(logging from the test suite.)
})
HTML5 Jump-Start
Whether youre an experienced web developer or someone looking to get into HTML5 web
development, the code generated by the HTML5 Boilerplate site can help jump-start your projects and also serve as a good learning environment. HTML5 Boilerplate includes several tips
and tricks to handle cross-browser issues that crop up, implements proven best practices, and
ultimately simplifies the process of writing HTML5-compliant web pages. Although the code
generated by HTML5 Boilerplate only provides skeleton HTML/CSS/JS code, you can visit other
sites such as initializr.com that build on the skeleton code while supplying functional pages with
graphics and placeholders.
The next step is to determine whether the browser supports the necessary drag-and-drop APIs along
with the browser-based file-reading APIs. This is done by using the following code:
var supported = ((Modernizr.draganddrop) &&
(typeof (window.FileReader) != undefined));
This code uses the Modernizr library to determine whether the browser supports the necessary dragand-drop interface. If the browser in use supports drag and drop, the value true is returned. The next
step is to check the browser for file-reader support. Once we have determined whether the browser
supports drag and drop and file-reading APIs, our code will then really get going.
Figure 2 shows the sample code for determining whether the application should display the drag-anddrop file user interface or the old-style upload interface.
Figure 2: Determining the file-upload interface style
dz = $(#dropArea);
dropZone = dz[0];
dz.removeClass(error);
isdnds = IsDragAndDropFileUploadSupported();
old = $(#oldUpload);
if (isdnds) {
dz.text(startUpText);
old.hide();
In this code, we need to get references to the dropArea div and the oldUpload div area. If the browser
supports drag and drop as well as the FileReader APIs, the oldUpload div area is hidden. If the
browser does not support drag and drop and the FileReader APIs, the dropArea div is hidden. Figure 3
shows how the upload interface will appear, depending on browser type.
Remember when we got the array of files to be uploaded? The file array was saved off in a page-level
object. Our code will pass in a reference to the first element in the array (the zeroth element). The
code will then get it and manually create an XMLHttpRequest object. If you have peeked ahead in
this article, you may be wondering why this is sent whe
n the server-side code to accept the upload looks for the files ContentType. The reason is that the
ContentType does not always come through. For example, the current version of the Chrome browser
and the preliminary developer version of IE10 dont seem to expose the ContentType, whereas Firefox
seems to send the ContentType. Sending the filename enables the server side to also see that we have
some data that we can pull out regarding the filename -- more specifically, the file extension.
Server-Side Code
Finally, lets look at the server code for uploading files, shown in Figure 6. Files in the upload process
need to be saved to a location on the server. In this case, well get a directory to save the files via the
Server.MapPath method. The next step is to create a unique filename, which we do with a GUID, and
then get a file extension. We can always use the filename that is uploaded in the header. The content
type is also available.
Figure 6: Server-side code for uploading files
public void ProcessRequest (HttpContext context) {
// Save Files
var localDir = context.Server.MapPath(~/files);
var contentType = context.Request.ContentType;
string fileExtension = String.Empty;
if (!String.IsNullOrEmpty(contentType))
{
fileExtension = context.Request.ContentType.Split(/.ToCharArray())[1];
}
Security
If youre focused particularly on security, you might have looked at the preceding code examples with
horror and thought, Oh my, you mean a browser can read files on my system and magically upload
them to a web server? This is horrible, and we never want to enable or turn on any HTML5 stuff
ever. Or maybe you are running through the halls of your office screaming this in terror. To address
security concerns, the World Wide Web Consortium (W3C) working draft for drag and drop includes
the following information about implementing security in the browser:
Data is not added to the DataTransfer object until the drop event occurs. This keeps data from
being made available during the other events.
A drop is only successful if a drop event is caused by the user. If a script attempts to implement a
drop event, the browser is not supposed to fire the drop event.
File Reading
The DataTransfer object is part of the drag-and-drop specification. The DataTransfer object contains
the files that have been selected. The files are made available to us through the FileReader window
interface, which is a part of the File API W3C Working Draft. In our file-upload code, we are using
the .size and .name properties of the files, which are fairly self-explanatory. Some of the other properties that are available are type, mozSlice, mozFullPath, fileSize, webkitRelativePath, fileName, and
webkitSlice. The properties that have the moz prefix are available on Firefox. The properties that
have the webkit prefix are available on Chrome. I expect that other browser vendors have created
their own properties as well.
You can test the browser on your own and load browser support as necessary. Ive seen developers
do things like this:
<script> !window.google && document.write(<script src=gears_init.js><\/
script>);</script>
You can use Modernizr and a script loader named yepnope to load some JavaScript files. In this
situation, our code will perform a test to see whether the browser supports HTML5 geolocation, as
shown in Figure 7. If it does, the yep.js file is loaded. If the browser does not support HTML5 geolcoation, the nope.js file is loaded. Once the files are loaded, the complete event fires and the defined
function is called, which will output the results to a div on the page. Figure 8 shows the output in IE.
Figure 7: yepnope test for HTML5 geolocation support
yepnope([{
test: Modernizr.geolocation,
yep: [js/yep.js],
nope: [js/nope.js],
complete: function () {
output(document.getElementById(outputDiv));
}
}]);
Input Types
Over the years, many mechanisms have been created to provide date and time support. Applications may use third-party Web Forms controls, jQuery UI plug-ins, or another type of third-party support. Theres nothing wrong with this approach, but its always good to make application developers
lives easier so that we can provide higher-value support to our customers. As more browsers support
HTML5 input types, developers and users will have access to this functionality. For example, we
would like some easy way to get the following:
<input type=datetime id=dateStart name=dateStart />
In HTML5 for the ASP.NET Developer, I mentioned that there are some new input types in HTML5,
including support for various date and time inputs. How many web applications have you built that
use time and dates in some form? I cant think of any app that I have built that doesnt use date or
time. Opera was the first web browser to support the date and time HTML5 input types, and now
iOSs mobile Safari has this support as well. ASP.NET MVC developers have immediate support for
HTML5 because these developers are responsible for building the user interface. But what about ASP.
NET Web Forms developers? HTML5 support will be built into .NET Framework 4.5, but it is not
available currently for a production setting. What can developers do now?
Thankfully, there is a solution that Web Forms developers can use now to enable date and time support in their web apps. To do so, Web Forms developers can use the following server-side code:
<asp:TextBox ID=dateText type=date runat=server />
Note that this code requires jQuery and jQuery UI, so you have to add in the necessary scripts to use
it, as shown in Figure 9.
Figure 9: Calling jQuery and jQuery UI scripts to display a calendar in a Web Forms app
<link rel=stylesheet href=http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css type=text/css media=all />
<link rel=stylesheet href=http://static.jquery.com/ui/css/demo-docs-theme/
ui.theme.css type=text/css media=all />
<script type=text/javascript src=http://code.jquery.com/jquery-1.6.4.min.
js></script>
<script src=https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.
min.js type=text/javascript></script>
Figure 10 shows the results of using the datetime input type to display a calendar in iOS 5 (left) and
IE9 (right). And there you have it: Web Forms developers can start using some of these new HTML
input types now and not have to wait for .NET 4.5.
Figure 10: Using HTML5s datetime input type to display a calendar in iOS 5 and in IE9 using
jQuery
Debugging
The combination of Visual Studio and Internet Explorer results in a great experience for developers,
but how can developers debug in Firefox and Chrome? After all, Visual Studio hooks directly into IE
but doesnt seem to have the same support for other browsers. Thankfully, there are solutions to this.
Firefox has Firebug (a Firefox plug-in), which provides JavaScript debugging as one of its features.
Chrome has some debugging tools built into it as well. Figures 11 and 12 show examples of debugging using the Chrome and Firefox tools.
Though its exceedingly simple, this code will allow you to determine the properties of an object. This
is helpful when you are running in a browser for which you dont have an available debugger.
Chapter 10: Ease HTML5 Web Development with jQuery, Knockout, and Modernizr Libraries 95
By Richard Campbell
HTML5 has opened the door to a significant number of new features and capabilities in the browser.
Unfortunately, those capabilities vary from version to version, and developers must consider browsers
that arent HTML5 compatible. Its really too much for one developer to handle, and being productive
in the todays web development world means using frameworks and libraries. So which development
frameworks and libraries should you use? The most ubiquitous library for web development, at least in
the Microsoft space, is the jQuery library. Today, jQuery has evolved into the jQuery Core and jQuery
UI versions. In jQuery Core, key JavaScript techniques, such as traversing a web documents objects,
handling events, and even directly coding AJAX, are simplified with this library. Microsoft has also
contributed to the jQuery library and includes the library with many of its latest web technologies.
jQuery UI is useful for handling effects and widgets for the browsers UI. Built on top of jQuery Core,
jQuery UI works with CSS to create theme frameworks for a consistent UI across all of your pages, as
well as handling animations, shading, and other more advanced effects.
But the most important aspect of jQuery is that it works equally well across all major browsers, even
Internet Explorer (IE). And thats the hard part of todays web developmentthere are so many different browsers (with new versions are released every few months) and trying to keep up with the
changing capabilities of todays browsers will make you crazy. Utilizing jQuery for document traversal
means that you dont have to deal with the changes caused by future browser versions. Instead, you
can download the latest version of jQuery and deploy it with your application.
Knockout is a JavaScript library that plays a similar role to jQuery, but for declarative data binding.
Clean-coded data access in web pages is a constant challenge and using a framework can greatly
simplify the process, as well as dealing with future changes. And, similar to jQuery, Knockout handles
all the different browsers that developers care about.
Although jQuery and Knockout take advantage of HTML5, these libraries arent specifically focused
on HTML5, and todays web developers want to exploit the latest and greatest in HTML5. But what
96 Chapter10:EaseHTML5WebDevelopmentwithjQuery,Knockout,andModernizrLibraries
do you do about users with an older browser? This is where libraries such as Modernizr and CSS PIE
come in.
Modernizr uses a technique called polyfills that lets you write code that exploits new HTML5 features,
such as Location classes. The code degrades gracefully with older browsers that dont have HTML5
functionalities. CSS PIE helps level the playing field of CSS implementation across different versions of
IE. You can code for IE 9 and let CSS PIE deal with the older versions of IE.
There are many more libraries out there to help you be productive in this complex world of web
development; these four libraries that Ive described are only a few. Its well worth your time to look
for help rather than solve all web development problems yourself.
Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App 97
By Dan Wahlin
As web technologies continue to evolve, developers have to learn new technologies so that they can
build successful web-based applications that stand above the crowd. This can be a challenging proposition, especially for developers moving from desktop or Rich Internet Application (RIA) development
frameworks. To help developers learn the latest HTML5, Cascading Style Sheets Level 3 (CSS3), and
JavaScript technologies, several developer colleagues and I built a sample application for demonstration at Microsofts MIX 11 conference. The application, called Account at a Glance, takes advantage
of key web technologies and uses them to display brokerage account information to consumers. (See
the end of this article for the code-download URL.)
The application was built in Q1 2011 by Dan Wahlin (client-side and server-side coding); Corey
Schuman; Jarod Ferguson (client-side coding); and John Papa (Entity Framework Code First coding).
John Papa, Giorgio Sardo, and Scott Guthrie also provided feedback and offered several key suggestions and ideas that were incorporated into the application. Figure 1a shows the Account at a Glance
application as it was first conceived on a whiteboard, and Figure 1b shows how it ended up after the
project was completed.
98 Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App
Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App 99
100 Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App
This article provides an overview of the Account at a Glance application. Part 2 will provide details
about the client-side technologies used, including HTML5 features such as jQuery templates, SVG,
Canvas, and video.
Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App 101
actions and rendered using jQuery Templates that are dynamically loaded from the server. CSS is used
heavily throughout the application. The .css files are located in the Content folder.
The AccountAtAGlance.Model project contains the applications data-access functionality. The project
contains the Code First classes that define the structure of model classes used throughout the application and also a DbContext class named AccountAtAGlance.cs. The Repository folder contains dataaccess classes that perform Create, Read, Update, and Delete (CRUD) operations on behalf of the
application. LINQ technologies are used in the application to simplify the data-access code and provide filtering and sorting functionality. The application makes RESTful service calls to ASP.NET MVC 3
actions that expose data and objects defined in the AccountAtAGlance.Model project. It also calls out
to a Google financial service to retrieve stock quotes and simulates random market index quotes on a
timed basis.
The next sections provide details on the data-access technologies and web framework used in the
application.
Figure 4: Using the NuGet Package Manager Console to install Entity Framework 4.1 and Code First
POCOs are used to define entities used in the application. Figure 5 shows an example of the BrokerageAccount POCO class, which defines several different properties as well as three navigation
properties.
102 Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App
}POCO classes defined in the application are used to automatically generate the database that the
application uses. A class named AccountAtAGlance that derives from DbContext is used to query the
database, as shown in Figure 6. This class is located in the AccountAtAGlance.Model projects Repository folder.
Figure 6: The AccountAtAGlance class, which is used to query the database
using System.Data.Entity;
namespace AccountAtAGlance.Model.Repository
{
public class AccountAtAGlance : DbContext
{
public AccountAtAGlance() : base(name=AccountAtAGlance) { }
public DbSet<BrokerageAccount> BrokerageAccounts { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Exchange> Exchanges { get; set; }
Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App 103
public
public
public
public
public
public
public
public
The AccountAtAGlance class relies on the new fluent API to map some POCO classes to database
tables, such as mapping Security to Securities and Stock to Securities_Stock. This is accomplished by
overriding the OnModelCreating() method and defining the necessary mappings.
104 Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App
Classes that follow the Repository Pattern are located in the Repository folder of the AccountAtAGlance.Model project. Several different classes are provided to handle various query functionality.
Figure 7 shows a section of the AccountRepository class that handles querying customer account
information. It uses the AccountAtAGlance DbContext class to perform the query.
Figure 7: The AccountRepository class, which uses DbContext to query the database for customer
account information
namespace AccountAtAGlance.Model.Repository
{
public class AccountRepository : RepositoryBase<AccountAtAGlance>,
IAccountRepository
{
public Customer GetCustomer(string custId)
{
using (var context = DataContext)
{
return context.Customers
.Include(BrokerageAccounts)
.Where(c => c.CustomerCode == custId).SingleOrDefault();
}
}
}
Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App 105
{
return Json(_SecurityRepository.GetSecurity(symbol),
JsonRequestBehavior.AllowGet);
}
Each action calls into the appropriate repository class, which handles retrieval of data from the
database. Once the data is retrieved and mapped to model objects, the objects are serialized to
JSON using the built-in Json() method in ASP.NET MVC controllers and passed back to the client for
processing.
An Integrated Approach
The Account at a Glance application provides a robust example of how different technologies can
integrate together from server side to client side. In this first article youve seen how the application
solution is structured and the different technologies that were used on the server side, including Entity
Framework Code First and ASP.NET MVC. In the next article Ill provide more details about the clientside coding and scripts that were used, including patterns that the team used to structure JavaScript
code. Until then, you can download the application code at the URL below if youd like to explore it
in more detail.
106 Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding
Chapter 12:
How to Build a jQuery HTML5 Web
Application with Client-Side Coding
Walk through client-side coding for the Account at a Glance App
By Dan Wahlin
As I discussed in Chapter 9, its important for web developers to get comfortable working with the
latest technologies, such as HTML5, Cascading Style Sheets Level 3 (CSS3), and JavaScript, so that
they can build leading-edge business applications. The Account at a Glance application, introduced
in last months article, demonstrates the use of a number of modern web development technologies.
In part 1, I talked about the back-end technologies used to build the Account at a Glance app: Entity
Framework 4.1 Code First and ASP.NET MVC 3. I also covered the data-access techniques used to
query the database, such as the Repository Pattern, as well as how C# model objects were converted
into JavaScript Object Notation (JSON) using ASP.NET MVC. In this article, the second and final
article in the series, Ill focus on the client-side aspect of the application and demonstrate a few of the
key HTML5, JavaScript, and jQuery features that it offers.
As a quick recap, the Account at a Glance application started as a simple whiteboard idea, shown in
Figure 1 (this was my good friend John Papas office whiteboard at Microsoft). John, Corey Schuman,
Jarod Ferguson, and I then took the whiteboard concept and created the final application, shown in
Figure 2. The application relies on multiple technologies, such as Entity Framework, ASP.NET MVC,
JSON, Ajax, jQuery, JavaScript patterns, HTML5 semantic tags, canvas, Scalable Vector Graphics
(SVG), video, and more.
Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding 107
108 Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding
3. Scene.statemanager.js also handles calling into a DataService object located in scene.dataservice.js,
which is responsible for accessing JSON data on the server using jQuerys Ajax functionality.
4. Once JSON data is available, scene.tile.binder.js handles the downloading of each tiles HTML template and binds the JSON to the template using jQuery Templates functionality.
5. Once the tiles have data, scene.tile.renderer.js handles rendering of the tiles in the page based
upon the target size (each tile has three different potential sizes).
6. Finally, tiles that need special formatting (such as canvas or SVG rendering) call into scene.tile.formatter.js, which performs custom functionality for different tiles.
The scene.layoutservice.js file contains a JSON array that defines all the tiles shown earlier in Figure
2. The tiles unique ID, layout scenes, and formatter (used for custom functionality) are defined in the
file. Figure 4 shows an example of a single tiles definition.
Figure 4: Defining tiles in the scene.layoutservice.js file
{ name: Account Details,
tileId: AccountDetails,
formatter: TileFormatter.formatAccountDetails,
scenes: [
( height: s1Mh, width: s1Mw, top: 0, left: 0, opacity: 1, size: 1,
borderColor: #5E1B6B, z: 0 },
height: 90, width: 210, top: 80, left: 250, size: 0,
borderColor: #5E1B6B, z: 2000, opacity: .5 }
]
}
Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding 109
renderTile = function(json, tile, fadeInAmount) {
TileBinder.bind(tile, json, TileRenderer.render);
}
Looking through the code in Figure 5, you can see that it calls a TileBinder object (located in scene.
tile.binder.js). Figure 6 shows the scene.tile.binder.js script that is used to convert JSON data retrieved
from the server to HTML using jQuery templates. The TileBinder object (as well as others within the
Account at a Glance application) follows the JavaScript Revealing Module Pattern detailed here.
Figure 6: Scene.tile.binder.js, which uses jQuery templates to bind JSON data to HTML templates
//Handles loading jQuery templates dynamically from server
//and rendering them based upon tile data
var TileBinder = function () {
var templateBase = /Templates/,
bind = function (tileDiv, json, renderer) {
var tileName = tileDiv.attr(id);
$.get(templateBase + tileName + .html, function (templates) {
$(body).append(templates);
var acctTemplates = [
tmpl(tileName, Small, json),
tmpl(tileName, Medium, json),
tmpl(tileName, Large, json)
];
tileDiv.data().templates = acctTemplates;
tileDiv.data().json = json;
renderer(tileDiv);
});
},
tmpl = function (tileName, size, json) {
var template = $(# + tileName + Template_ + size);
if (json != null)
return template.tmpl(json);
else
return template.html();
};
return {
bind: bind
};
} ();
110 Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding
The bind() function shown in Figure 6 receives the tile that must be rendered, the JSON data used to
render it, and a renderer object that handles placing rendered HTML into the appropriate container in
the page displayed to the user. The bind() function uses the jQuery get() function to call the server and
retrieve the small, medium, and large templates for a given tile.
The different template sizes for a tile are defined in a single file that lives within the AccountAtAGlance projects Templates folder. Figure 7 shows an example of templates used to render the S&P
500 tiles. The ${ token } token syntax found in each of the templates defines the JSON properties that
should be bound once each template is rendered. See my blog post Reducing Code by Using jQuery
Templates for more details about jQuery templates.
Figure 7: HTML templates used along with jQuery template functionality to render the S&P 500 tiles
<script id=SP500Template_Small type=text/x-jquery-tmpl>
<div class=content>
<header>
<div class=Left>S&P 500</div>
<div class=MarketQuoteLast Right>${ SP500.Last }</div>
</header>
<section>
<div class=MarketQuoteDetails>
{{tmpl #SP500QuoteDetails_Template }}
</div>
</section>
</div>
</script>
<script id=SP500Template_Medium type=text/x-jquery-tmpl>
<div class=content>
<header>
<div class=Left>S&P 500</div>
<div class=MarketQuoteLast Right>${ SP500.Last }</div>
</header>
<section>
<div class=MarketQuoteDetails>
{{tmpl #SP500QuoteDetails_Template }}
</div>
<div id=SP500Canvas class=canvas></div>
</section>
</div>
</script>
<script id=SP500Template_Large type=text/x-jquery-tmpl>
<div class=content>
<header>
<div class=Left>S&P 500</div>
<div class=MarketQuoteLast Right>${ SP500.Last }</div>
Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding 111
</header>
<section>
<div class=MarketQuoteDetails>
{{tmpl #SP500QuoteDetails_Template }}
</div>
<div id=SP500Canvas class=canvas></div>
</section>
</div>
</script>
<script id=SP500QuoteDetails_Template type=text/x-jquery-tmpl>
<span class=MarketQuoteChange>{{if parseFloat(SP500.Change) > 0}}+{{/if}}
${ SP500.Change }
</span>
<span class=MarketQuotePercentChange>${ SP500.PercentChange }%</span>
</script>
The tile templates rely on HTML5 semantic elements such as header and section to define containers
for content. Each tile uses these elements in a similar manner.
The ID of the tile defined in the scene.layoutservice.js file (see Figure 4) determines which template
file to download -- convention is used for this functionality. Once the template for a given tile is
downloaded, it is added into the body of the page using the jQuery append() function. Then each
tile size is rendered by calling the tmpl function, shown in Figure 6. As the different tile sizes are rendered, theyre stored along with the JSON data in the tile by using the jQuery data() function.
The final step in the process is to call the tile renderer passed into the bind() function (see Figure 6) to
load the appropriate tile size into the page. Figure 8 shows the renderer object (called TileRenderer)
that is responsible for adding HTML content into the page for display to the user.
Figure 8: The scene.tile.renderer.js file defining a TileRenderer object
var TileRenderer = function () {
var render = function (tileDiv, sceneId) {
if (sceneId == null) {
sceneId = 0;
}
var size = tileDiv.data().scenes[sceneId].size,
template = tileDiv.data().templates[size],
formatterFunc = tileDiv.data().formatter;
tileDiv.html(template);
if (formatterFunc != null) {
formatterFunc(tileDiv);
}
};
return {
render: render
};
} ();
112 Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding
Figure 9: The Quote tile, which uses the canvas tag to render a stock quote chart
Figure 10: Using the Flot jQuery plug-in to render a canvas chart
renderCanvas = function(canvasDiv, width, height, color, itemJson, dataPointsJson) {
if (dataPointsJson != null && dataPointsJson.length > 0) {
var quoteData = [];
for (var i in dataPointsJson) {
var dp = dataPointsJson[i];
quoteData.push([dp.JSTicks, dp.Value]);
}
var maxY = itemJson.Last + (itemJson.Last * .3);
var chartOptions = {
series: {
lines: { show: true, fill: true },
points: { show: true, radius: 5 }
},
Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding 113
grid: { hoverable: true, autoHighlight: true },
legend: { position: se },
yaxis: { max: maxY, min: 0 },
xaxis: { minTickSize: [1, hour], mode: time, timeformat: %h %P,
twelveHourClock: true }
};
canvasDiv.attr(style, width: + width + px;height: + height + px;);
//Required....css() doesnt work properly for this
$.plot(canvasDiv, [{
color: color,
shadowSize: 4,
label: Simulated Data,
data: quoteData
}], chartOptions);
canvasDiv.bind(plothover, function(event, pos, item) {
if (item) {
if (previousPoint != item.datapoint) {
previousPoint = item.datapoint;
$(#CanvasTooltip).remove();
//var x = item.datapoint[0].toFixed(2),
var y = item.datapoint[1].toFixed(2);
showTooltip(item.pageX, item.pageY, y);
}
}
else {
$(#CanvasTooltip).remove();
previousPoint = null;
}
});
}
}
Figure 11 shows the SVG chart displayed in the Account Details tile that is used to display security
positions within the account.
Figure 11: The SVG positions pie chart displayed in the Account Details tile
114 Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding
Its generated using a jQuery plug-in named Raphael along with a specific Raphael plug-in used to
handle pie charts (Raphael-pie.js in the project). Figure 12 shows the code that handles rendering the
positions pie chart.
Figure 12: The Raphael jQuery plug-in, which is used to render an SVG chart
formatAccountDetails = function(tileDiv) {
tileDiv.find(.Currency).formatCurrency();
var scene = tileDiv.data().scenes[0];
if (Modernizr.inlinesvg) {
if ($(#AccountPositionsSVG).length > 0) {
var values = [];
var labels = [];
$(tileDiv.data().json.Positions).each(function() {
labels.push(this.Security.Symbol + \r\n + this.Shares + shares);
values.push(this.Shares);
});
raphael(AccountPositionsSVG, 500, 420).pieChart(scene.width / 2, scene.height
/ 4 + 10, 66, values, labels, #fff);
}
}
}
Integrating Video
Video is an important part of many web-based applications and is used in the Account at a Glance
application to display video news, as shown in Figure 13.
Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding 115
<video id=VideoPlayer controls
preload=auto poster=/content/images/video-poster.jpg>
<source type=video/mp4 src=.../031411hubpmmarkets_320k.mp4 />
</video>
116 Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development
Chapter 13:
Explore the New World
of JavaScript-Focused Client-Side
Web Development
Learn about the scripts and tools that can help you
write JavaScript client-side apps
By Dan Wahlin
It was fairly easy to figure out client-side web development 10 years ago. If an application needed
to run consistently across browsers, HTML was dynamically generated on the server and sent to the
browser for rendering. Some of the more modern applications integrated Ajax and JavaScript into the
mix, but many apps worked with little or no JavaScript at all. Although I personally enjoyed working
with JavaScript back then, it wasnt exactly the most popular language on the planet, and many developers avoided JavaScript entirely because of a variety of issues associated with it.
In situations in which web-based applications required rich client-side functionality, Adobe Flash
was used because it provided animation, media services, and a host of other features that HTML,
Cascading Style Sheets (CSS), and JavaScript couldnt offer. Around 5 years later, Silverlight began its
rapid evolution as a client-side rich Internet application (RIA) development option. The world of RIAs
looked extremely bright. Then the RIApocalypse occurred, and things seemed to change in the blink
of an eye.
RIA frameworks such as Flash and Silverlight are certainly still viable for building different types of
applications and offer some functionality that isnt quite ready yet in HTML5 or JavaScript. However,
over the past 2 years, technology has quickly moved in a different direction for applications that need
to reach a broad audience. As a consequence of the large increase in the number mobile devices in
use, more powerful CPUs, more memory, and easier access to wireless data (and lets not forget the
iPad and Apples general view toward plug-ins), a major shift has occurred that has ushered in the rise
of HTML5 and JavaScript.
Some developers like the shift; some developers hate it. Regardless of which side of the fence youre
on, the shift has happened, and it has definitely had an effect on the way applications are built. My
intent here is to help you negotiate the shift by providing an overview of the current state of clientside development and some popular scripts and tools that will help you build robust client-centric
web applications.
Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development 117
118 Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development
an Ajax call, you can write code similar to the following to make the call and let jQuery handle the
rest:
$.getJSON(/DataService/GetCustomer, { id: custID }, function(data) {
//process data returned from the controller action
});
jQuerys core strength lies in its ability to easily select DOM elements using a small amount of code.
For example, to find all li elements in divs that have a panel class on them, you can use the following
jQuery selector:
var liTags = $(div.panel li);
After one or more nodes are found, you also attach events in a cross-browser manner using shortcut
functions, as shown next. (You could also use bind(), on(), or other similar functions.)
liTags.click(function() {
var li = $(this); //grab clicked item
//do something!
});
This technique significantly minimizes the amount of code required to locate DOM nodes, the text or
HTML within the nodes, or even attributes. It can also be used to animate elements, add or remove
nodes, and do much more. Also available are script libraries based on jQuery, such as jQuery UI
and jQuery Mobile. jQuery UI provides a set of widgets and effects that can be used to render dialog
boxes and pop-up calendars, add drag-and-drop and autocomplete functionality, and add other capabilities. jQuery Mobile is a relatively new script library that provides a simple yet robust way to build
mobile-enabled websites that work well on many types of mobile devices.
When you include jQuery and jQuery Mobile scripts in a page, HTML5 data attributes can be used
to define one or more mobile pages that resize dynamically to different device sizes. Figure 1 shows
an example of using jQuery Mobiles data-role attribute to define multiple mobile pages. As the div
elements in Figure 1 are processed by jQuery Mobile, theyre automatically converted into pages that
can be navigated to by the user.
Figure 1: Data attributes used to define pages for mobile sites with jQuery Mobile
<body>
<div data-role=page
</div>
<div data-role=page
</div>
<div data-role=page
</div>
<div data-role=page
</div>
id=home>
id=products>
id=about>
id=contact>
Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development 119
</body>
In addition to script libraries such as jQuery UI and jQuery Mobile, thousands of jQuery plug-ins are
also available that can be used to render grids, show charts, display images, play videos, and provide
many other types of features. The large number of jQuery plug-ins plays a big part in jQuerys overall
popularity.
Although jQuery is extremely popular, it can be overkill in some cases in which only a subset of the
functionality it offers is needed. Future versions of jQuery will provide more modular script options
that let you select the specific functionality youd like (resulting in smaller scripts being used in an
application). For now, when you need only a subset of jQuery features, you can use alternative scripts
such as zepto.js or xui. Zepto.js is less than one fourth the size of jQuery yet provides many features.
Zepto.js isnt designed to work on older browsers and wasnt built with Internet Explorer (IE) in mind;
even so, it can be an appropriate choice in some situations. Xui is designed to work specifically with
the DOM and is only around 4KB in size when compressed.
In addition to core script libraries such as jQuery, jQuery UI, jQuery Mobile, and others, several additional scripts are available to fill different client-side development needs. Because of space constraints,
I wont provide an exhaustive discussion of these scripts here, but I can mention a few of the more
interesting ones. Figure 2 lists some scripts that have been getting a lot of attention lately.
Figure 2: Scripts that can be used in web apps to simplify coding and provide core functionality and
frameworks
Script
AngularJS
Description
AmplifyJS
Backbone.js
Bootstrap
Bootstrap provides UI components and interactions. Components are built with responsive design in mind, so that they
adjust to different resolutions and devices.
JsRender
JsRender, a replacement for jQuery Templates, allows clientside templating that can significantly reduce the amount of
JavaScript code required to convert JSON data to HTML.
KnockoutJS
LESS
Underscore
Underscore provides many helpful utility functions for JavaScript, such as sorting arrays, grouping items, finding min and
max values, and many others.
120 Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development
This list barely scratches the surface of whats out there, especially given that Ive handpicked only a
few scripts. You can find a list of some of the more popular JavaScript files currently used in websites
on BuiltWiths JavaScript Libraries Growth page. Third-party companies such as Telerik, Infragistics,
and others have also released script libraries.
In addition to script libraries, another topic thats relevant for todays web applications is responsive
design and CSS media queries. More and more sites now support multiple resolutions and screen
sizes. These sites respond dynamically to the screen size that a webpage is displayed in and fill it
accordingly. Todays modern browsers support CSS media queries that can be used to target specific
screen sizes. By using media queries appropriately, you can enable a website to look good in the
browser, on a mobile device, and even on a tablet. The following example shows a simple CSS media
query to override CSS styles when a device is 320 pixels wide:
@media screen and (max-width:320px) {
/* override default styles here */
nav ul > li {
float: none;
}
}
Feature Detection
Although nearly all modern browsers support HTML5 and CSS3 features, they dont consistently support the same set of features. Given the number of existing browsers and browser versions, knowing
what features a particular browser supports is crucial. In the old days, wed rely on general browser
detection to determine what HTML or JavaScript to load, but that doesnt work well now. We need a
more fine-grained approach that determines specific features supported by a browser.
You can use the Modernizr script library to detect specific features supported by a browser. Modernizr can test for the presence of CSS3 features, canvas support, geolocation, animations, and much
more. In fact, its capable of testing more than 40 features across multiple browsers. Modernizr also
adds feature-specific CSS classes, such as no-touch, cssanimations, cssgradients, and opacity to the
root <html> element as appropriate. These classes can be used to enable or disable CSS styles in an
application.
The following code shows an example of using Modernzr to test for HTML5 canvas support:
if (Modernizr.canvas) {
//get canvas and 2d context
}
else {
//run fallback code
}
The Modernizr object shown in this code example is made available by including the modernizr.js
script in your web page. After the Modernizr object is available, you can test for many different fea-
Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development 121
tures. For example, you can test for the presence of CSS3 features such as rounded corners using the
following code:
if (Modernizr.borderradius) {
//rounded corner support is available
}
In situations in which a feature isnt available, Modernizrs YepNope functionality can be used to load
a polyfill script. A polyfill is a script designed to fill in missing features in older browsers. (See the
HTML5 Cross Browser Polyfills page on GitHub for a nice list of polyfills.) Following is an example
of using Modernizr to detect features, then dynamically load different scripts:
Modernizr.load({
test: Modernizr.canvas,
yep : canvas.js,
nope: canvas-polyfill.js
});
This code tests for the presence of the HTML5 canvas in a browser and loads canvas.js if its supported. If the browser doesnt support the HTML5 canvas, a polyfill script named canvas-polyfill.js
is loaded instead to provide fallback functionality (note that multiple scripts can be loaded as well).
Using Modernizr gives you an edge in building cutting-edge web applications that take advantage of
new HTML5 and CSS3 features while still providing graceful fallbacks for older browsers.
Web Tools
One of the big complaints I hear about JavaScript is that no good tools exist for writing and debugging JavaScript code. It turns out there are actually many great editors available to help you write
JavaScript. Tools such as Sublimeand Notepad++ provide text-editing functionality with support for
code highlighting, plug-ins, and more features, and browser-based tools such as Cloud 9 IDE or
CodeMirror are also available. If you want more robust features and integrated debugging, Aptana
Studio or Visual Studio 2012 provide excellent JavaScript features and the ability to set breakpoints,
step through code, and other features.
Some of the best available tools are free and built directly into modern browsers. IE, Firefox, Safari,
and Chrome have integrated developer tools that can be used to tweak HTML, CSS, and JavaScript
live in the browser while youre viewing a site. Although my personal favorite is the Chrome Developer Tools, similar functionality is available across all the major browsers. In most cases, you access
these tools by pressing F12 or via the browsers Options menu.
Figure 3 shows an example of the Chrome Developer Tools in action.
122 Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development
Figure 3: Using the Chrome Developer Tools to view HTML and CSS
HTML from the page is shown on the left, and styles, margins, borders, and other metrics are on the
right. You can tweak HTML and CSS directly in the tool, and changes are reflected immediately in the
page. Ive found this capability very helpful when I need to figure out where extra padding is coming
from or get a live view of how a particular change will affect a page.
You can also debug JavaScript directly in the tool without having to leave the browser and jump back
to another editor. To debug a script, select the Scripts tab, pick the script from the tree thats displayed
at the left, then click in the left gutter area to set a breakpoint. Figure 4 shows an example.
Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development 123
Chapter 14:
Storing Your Data in HTML5
Get a feel for working with HTML5s flexible web storage
By Daniel Egan
In the world of application development, data rules. Every application, whether on the desktop or
web, requires the storage of some sort of data, and developers have been saving their stuff in different places for many years. There have been many techniques to store information on the web. From
cookies to sessions to forms, working in a stateless world has always been a challenge. In this months
article, we are going to continue on the developer side and look at one of the more useful and widely
needed aspects of HTML5: web storage.
In the Beginning
You will hear web storage called different things: DOM storage, local storage, HTML5 storage. But its
true name, as defined by the HTML5 Web Storage specification, is web storage.
The cool thing about web storage is that it is supported by all the major browsers, including mobile
browsers:
On the desktop:
Microsoft Internet Explorer (IE) 8 and later
Mozilla Firefox 3.5 and later
Apple Safari 4 and later
Google Chrome 4 and later
Opera 10.5 and later
On mobile devices:
Windows Phone 7 and later
A mostly arbitrary limit of five megabytes per origin is recommended. Implementation feedback is
welcome and will be used to update this suggestion in the future.
This size is supported in most browsers (i.e., Firefox, Chrome, and Opera), although IE supports 10MB
(or as the documentation puts itqueue the Dr. Evil voice10 million bytes). In addition, Opera
allows the user to decide how much storage each site can use, although this figure is not known to
the developer at design time. Because you will need to make sure that your web application works
across all browsers, I suggest keeping the 5MB in mind while developing. If you exceed this limit,
you will receive a QUOTA_EXCEEDED_ERR and will need to process that error appropriately. At this
point, if you are used to other mediums, such as Adobe Flash or Silverlight, you might be wondering
whether you can prompt the user to request additional space. Unfortunately, the answer is no.
Since we do not live in a perfect world, you will have users running browsers that do not fit into the
previous list. Therefore, you will need to check whether the browser supports web storage. You can
use the following code to do so:
function supportsStorage() { return (localStorage in window) &&
window[localStorage] !== null;
}
You can use this code as shown in Figure 1; this code allows you to perform a simple check whenever
you attempt to save something to storage.
Figure 1: Checking whether a browser supports HTML5 web storage
if (!supportsStorage()) {
alert(Your browser does not support HTML5 localStorage. Try upgrading.);
} else {
try {
//save something
} catch (e) {
if (e == QUOTA_EXCEEDED_ERR) {
alert(Quota exceeded!);
//save some other way??
}
}
}
As you can see, we are also catching the specific quota exceeded error so that we can handle it
and alert the user. You can then decide the best option for your application: using a different storage
Different authors sharing one host name, for example users hosting content on geocities.com, all share
one local storage object. There is no feature to restrict the access by pathname. Authors on shared
hosts are therefore recommended to avoid using these features, as it would be trivial for other authors
to read the data and overwrite it.
So be certain that you know who is writing applications for the domain that you are using, or you
expose your saved data to others. In addition, do not save sensitive data in web storage. Anyone
sharing your domain would find it all too easy to loop through and read your data.
Before we dive too deeply into the saving of data, you need to know that there are actually two types
of defined storage: session storage and local storage.
Session Storage
Session storage is designed for scenarios in which the user is carrying out a single transaction. The
HTML5 sessionStorage attribute is available only to the window or tab in which it was initiated and
only while that window stays active. When the window or tab is closed (i.e., the session has ended),
the data ceases to exist. This approach has an advantage over cookies, not only because you have
more room to store data (5MB versus 4KB for a cookie), but because this attribute is scoped only for
the window that is open. Cookies can leak to another window if you open another browser instance
while your session is still active.
Local Storage
Local storage is designed for scenarios in which you want the data to persist beyond a single session.
This storage spans all windows that you might have open on that domain. If you set or modify data in
one window, that data will be available to all other windows that are opened to that domain. In addition, the data stays available after you close your browser, unless explicitly deleted by the developer
or user. This approach allows you to store data over instances, across windows, and on the client side,
without using cookies.
If you want to save your fingers from doing some typing, then you can also use Expandos to add and
retrieve data:
sessionStorage.firstName = Daniel;
sessionStorage.LastName Egan;
var fName = sessionStorage.firstName;
var lName = sessionStorage.lastName;
Understanding that all data is saved as a DOMString is vital for several reasons. First, because the
API stores numbers as strings, a developer needs to be sure to convert numbers when retrieving data,
as the example in Figure 2 shows. Remember that the + symbol serves a dual purpose: It performs
both arithmetic and concatenation. Second, as a developer you wont be limiting yourself to simple
key/value pairs, so you will need a way to store more complex structures as strings.
If we want to store this object in session storage, we can encode and decode it, using the JSON.stringify and JSON.parse methods. First, we save the object to storage:
sessionStorage.setItem(person, JSON.Stringify(person));
Clearing Data
Now that we have filled our storage with data, we need a way to remove it. There are two ways to
remove data that you have placed in storage: removeItem and clear. The removeItem method is very
similar to getItem, in that if you pass it a key, it will remove the value associated with that key:
If you want to remove everything that you have stored in storage, you can use the clear method:
sessionStorage.clear();
Keep in mind that the examples we have been using are for session storage and will go away when
the browsing session is completed. The same is not true for local storage. Because we have a limit of
5MB per domain, make sure that you keep your storage area clear.
In this article, we have focused specifically on web storage as a way to store data locally. As we mentioned previously, web storage has been widely implemented across all major browsers. This type of
storage is a step up from cookies and is a much simpler and cleaner way to save your data, whether
you need to save information for one session or across sessions.
Chapter 15:
Using the HTML5 Canvas Tag
The HTML5 canvas tag expands your options
for rendering text, images, shapes, and more
By Dan Wahlin
Rendering complex graphs or designs to the web has always been a challenge that has typically
been solved by using images, server-side processes, or plug-ins such as Silverlight or Flash. Although
drawing charts with straight lines has never been a problem (with the use of some creative CSS), rendering different types of shapes and colors natively in the browsersuch as ellipses, Bzier curves,
and other custom shapeshas always been a problem. With the addition of the HTML5 canvas tag,
available in the latest version of all major browsers, you can now do a lot using only JavaScript and
HTML tags. In this article Ill provide an introduction to the canvas tag and demonstrate some of the
fundamental tasks you can perform using it.
Figure 1: Putting the canvas into action with other HTML5 features such as audio and video
Before jumping into a discussion of using the canvas, lets take a moment to consider why youd want
to use it instead of using Silverlight, Flash, or server-side image generation processes. Determining
when to use the canvas (or, in my mind. any HTML5 feature) comes down to the target audience.
For example, Im a big fan of Silverlight in addition to web technologies. If Im building a line of
business (LOB) application that will be deployed on only Windows or Macintosh machines using
in-browser or out-of-browser techniques, then Ill generally look to Silverlight first since it works very
well in that scenario and brings a lot of power and productivity to the table. However, if Im writing
an application that will be released on the Internet or an intranet and may be used by different
devices such as iPads or iPhones, Android phones and tablets, or others, then Ill pick standard web
technologies. Every application is different and I dont believe that one size or technology fits all. Of
course, youll have to evaluate whether your target users have browsers that support the canvas tag
and plan an alternative strategy if they dont. The canvas is definitely a new feature and not supported
by many older browsers including pre-IE9 Internet Explorer versions.
Now lets get started with an overview of how to define and interact with the canvas.
Once a canvas is defined (or dynamically added) in HTML, you can interact with it using standard
JavaScript. I generally prefer to use jQuery in any JavaScript-oriented page, but you can also use the
standard document.getElementById() function to locate a canvas tag and then interact with it. The following code demonstrates how to locate a canvas tag defined in a page and get access to its 2D context for drawing:
<script type=text/javascript>
window.onload = function () {
var canvas = document.getElementById(canvas);
Notice that once the canvas object is located, you must access its 2D drawing context. The W3C
defines the 2D context: The 2D context represents a flat Cartesian surface whose origin (0,0) is at the
top left corner, with the coordinate space having x values increasing when going right, and y values
increasing when going down.
You can think of the 2D context as the drawing surface that youll programmatically interact with
using JavaScript. Once you have a reference to the 2D context object, you can use methods such as
lineTo(), fillText(), and fillRect() to perform drawing operations. Lets take a look at a few of the drawing
features available.
Drawing Shapes, Lines, and Text
If youve ever used GDI+ (Graphics Device Interface) in the .NET framework (System.Drawing
namespace), youll feel right at home using the canvas since its similar to GDI+ drawing in many
ways. If youve never touched GDI+, then dont worry about it; its simple to get started using the
canvas once you know a few fundamentals. Drawing is accomplished by calling standard JavaScript
functions that handle rendering lines, shapes, colors, styles, and more. Figure 2 shows several of the
key functions you can use.
In this example, the 2D context has its fillStyle set to a color of Green. The square thats rendered by
calling fillRect() will be displayed in the upper left of the screen (0,0 point) and have a width of 200
and a height of 100.
If youd like to render an arc or circle, the arc() function can be used. It has the following signature:
arc(centerX,centerY,radius,startAngle,endAngle,antiClockwise);
The centerX and center Y parameters define where the middle of the ellipse will be, the radius defines
the size of the ellipse, and the startAngle and endAngle parameters control the start and end points
of the ellipse (note that the startAngle and endAngle parameters are defined using radians rather than
degrees). The antiClockwise parameter will draw an arc (part of a circle) in an anticlockwise direction
when set to true. Heres an example of using the arc() function:
//Render a circle
ctx.arc(100, 200, 50, 0, 2 * Math.PI, false);
ctx.fillStyle = Navy;
ctx.fill();
Passing a value of 0 and 2 * Math.PI for the start and end angle parameters will result in a complete
circle being rendered. To render part of a circle, simply supply a different value for the startAngle or
endAngle parameter, as shown next. This example will result in 1/2 of a circle being rendered. Figure
4 shows the rectangle, circle and arc that are rendered to the canvas.
Its important to note that a call to beginPath() was performed before the arc() function call so that
each circle/arc shape stayed distinct and didnt merge into the following one as shown in Figure 5.
There are certainly other types of shapes you can draw with the canvas, including Bzier and quadratic curves. Theyre useful when you need to draw nonstandard shapes or add rounded corners to
something like a rectangle. The Mozilla canvas documentation provides an example of using lines and
quadatric curves to render a rectangle with rounded corners (see Figure 8).
Figure 8: Drawing a rectangle with rounded corners
function roundedRect(ctx, x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x, y + radius);
ctx.lineTo(x, y + height - radius);
ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
ctx.lineTo(x + width - radius, y + height);
ctx.quadraticCurveTo(x + width, y + height, x + width,
y + height - radius);
ctx.lineTo(x + width, y + radius);
ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
ctx.lineTo(x + radius, y);
ctx.quadraticCurveTo(x, y, x, y + radius);
ctx.strokeStyle = Black;
ctx.lineWidth = 10;
ctx.stroke();
ctx.fillStyle = Lime;
ctx.fill();
}
The final topic that Ill cover is text rendering. Although rendering shapes can be good for charts and
a variety of other tasks, at some point youll want to render text to a canvas. Fortunately, thats an easy
proposition and something thats also quite flexible since the canvas supports different types of transforms as well (e.g., scaling and rotating objects). To render text to the canvas, you can use the fillText()
method, which accepts the text to add as well as the x and y coordinates of where to add it. Heres an
example of using fillText():
ctx.fillStyle = Black;
ctx.font = 30pt Arial;
ctx.fillText(Drawing with the Canvas, 0, 550);
Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas 139
Chapter 16:
HTML5 Tutorial: Build a Chart
with JavaScript and the HTML5 Canvas
Learn how to use HTML5 to build charting features
such as lines, shapes, and gradients into your web applications
By Dan Wahlin
Download the code: http://www.devproconnections.com/content/content/139802/139802_CanvasDemos.zip
The HTML5 canvas is capable of rendering lines, shapes, images, text, and more without relying on a
plug-in. Although the canvas element isnt supported by older browsers, the latest version of all major
browsers (Internet Explorer, Safari, Chrome, Firefox, and Opera) now support the canvas, making it an
option for rendering charts, graphs, and other types of visual data. In cases where a browser doesnt
support the canvas, a fallback can be provided that renders data using Silverlight, Flash, or another
type of plug-in.
In Chapter 14, I walked through the fundamentals of using the HTML5 canvas to render different
types of shapes. In this article Ill discuss how the canvas can be used to render a line chart using
JavaScript. An example of the chart that will be discussed is shown in Figure 1.
140 Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas
Figure 2: Using a CanvasChart JavaScript object to render a chart using the HTML5 canvas
<!DOCTYPE html>
<html>
<head>
<title>Canvas Chart Demo</title>
<script src=Scripts/jquery-1.6.min.js type=text/javascript></script>
<script src=Scripts/canvasChart.js type=text/javascript></script>
<script type=text/javascript>
$(document).ready(function () {
var dataDef = { title: US Population Chart,
xLabel: Year,
yLabel: Population (millions),
labelFont: 19pt Arial,
dataPointFont: 10pt Arial,
renderTypes: [CanvasChart.renderType.lines,
CanvasChart.renderType.points],
dataPoints: [{ x: 1790, y: 3.9 },
{ x: 1810, y: 7.2 },
{ x: 1830, y: 12.8 },
{ x: 1850, y: 23.1 },
{ x: 1870, y: 36.5 },
{ x: 1890, y: 62.9 },
{ x: 1910, y: 92.2 },
{ x: 1930, y: 123.2 },
{ x: 1950, y: 151.3 },
{ x: 1970, y: 203.2 },
{ x: 1990, y: 248.7 },
{ x: 2010, y: 308.7}]
};
CanvasChart.render(canvas, dataDef);
});
</script>
< /head>
<body style=margin-left:50px;margin-top:50px;>
<canvas id=canvas width=800 height=600></canvas>
</body>
</html>
The render() function accepts the canvas element ID as well as a JSON object that defines chart properties and data to be used in the rendering process.
The CanvasChart object demonstrates several key features of the canvas element that can be used in
applications, including rendering lines, shapes, gradients, text, and even transformed text. Lets take a
look at how the CanvasChart object was created.
Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas 141
The code follows a JavaScript pattern referred to as the revealing module pattern, which provides a
convenient way to write objects that expose specific members only to outside callers. This example
exposes the renderType variable and render function.
The render() function shown in Figure 4 accepts the canvas ID defined within the page (see Figure 2)
as well as a JSON object that defines details about labels, font sizes, data points, and more that are
used for charting.
Figure 4: The render function, which is exposed to the client and used to trigger different canvasrendering processes
var render = function(canvasId, dataObj) {
data = dataObj;
getMaxDataYValue();
var canvas = document.getElementById(canvasId);
chartHeight = canvas.getAttribute(height);
chartWidth = canvas.getAttribute(width);
xMax = chartWidth - (margin.left + margin.right);
yMax = chartHeight - (margin.top + margin.bottom);
ratio = yMax / maxYValue;
ctx = canvas.getContext(2d);
142 Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas
renderChart();
};
The render function starts by assigning the dataObj parameter to a variable within the CanvasChart
object, then calls an internal function named getMaxDataYValue(). The getMaxDataYValue() function
determines the maximum Y value for the data points. From there, the render() function locates the
target canvas element within the page, calculates width and height values, and accesses the canvass
2D context that will be used to draw. Finally, a call is made to renderChart() to start the rendering
process.
The renderChart() function (see Figure 5) orchestrates different drawing functions and handles rendering the background, lines, labels, and data by calling the respective functions.
Figure 5: The renderChart function, which handles rendering a background gradient, text, lines, and
labels along the X and Y axes
var renderChart = function () {
renderBackground();
renderText();
renderLinesAndLabels();
//render data based upon type of renderType(s) that client supplies
if (data.renderTypes == undefined || data.renderTypes == null)
data.renderTypes = [renderType.lines];
for (var i = 0; i < data.renderTypes.length; i++) {
renderData(data.renderTypes[i]);
}
};
Different canvas features are used in the CanvasChart object, such as gradients and transforms. For
example, the renderBackground() function shown in Figure 6 demonstrates how linear gradients can
be created. The renderBackground() function uses the 2D contexts createLinearGradient() function to
define a gradient that has four gradient stops. Once the gradient is defined, it is assigned to the fillStyle property, then rendered to a rectangular area using the fillRect() function.
Figure 6: The renderBackground function showing how gradients can be rendered within a canvas
using the createLinearGradient function
var renderBackground = function() {
var lingrad = ctx.createLinearGradient(margin.left, margin.top,
xMax - margin.right, yMax);
lingrad.addColorStop(0.0, #D4D4D4);
lingrad.addColorStop(0.2, #fff);
lingrad.addColorStop(0.8, #fff);
lingrad.addColorStop(1, #D4D4D4);
ctx.fillStyle = lingrad;
ctx.fillRect(margin.left, margin.top, xMax - margin.left,
yMax - margin.top);
ctx.fillStyle = black;
};
Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas 143
CanvasChart also demonstrates how text can be manipulated using transforms. The text displayed on
the Y axis is rotated so that it displays vertically, as shown in Figure 7.
144 Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas
After the x and y axis text is rendered, the CanvasChart object makes a call to renderLinesAndLabels()
(see Figure 9) to handle rendering the horizontal and vertical lines.
Figure 9: Rendering lines and labels using the canvas
var renderLinesAndLabels = function () {
//Vertical guide lines
var yInc = yMax / data.dataPoints.length;
var yPos = 0;
var yLabelInc = (maxYValue * ratio) / data.dataPoints.length;
var xInc = getXInc();
var xPos = margin.left;
for (var i = 0; i < data.dataPoints.length; i++) {
yPos += (i == 0) ? margin.top : yInc;
//Draw horizontal lines
drawLine(margin.left, yPos, xMax, yPos, #E8E8E8);
//y axis labels
ctx.font = (data.dataPointFont != null) ? data.dataPointFont :
10pt Calibri;
var txt = Math.round(maxYValue - ((i == 0) ? 0 : yPos / ratio));
var txtSize = ctx.measureText(txt);
ctx.fillText(txt, margin.left - ((txtSize.width >= 14) ?
txtSize.width : 10) - 7, yPos + 4);
//x axis labels
txt = data.dataPoints[i].x;
txtSize = ctx.measureText(txt);
ctx.fillText(txt, xPos, yMax + (margin.bottom / 3));
xPos += xInc;
}
//Vertical line
drawLine(margin.left, margin.top, margin.left, yMax, black);
//Horizontal Line
drawLine(margin.left, yMax, xMax, yMax, black);
};
Lines are normally drawn using the 2D contexts moveTo() and lineTo() functions, which are wrapped
in a function named drawLine() to simplify the process. Figure 10 shows the drawLine function. At this
point the canvas looks like the image shown in Figure 11.
Figure 10: Wrapping canvas functionality for drawing lines into a function named drawLine
var drawLine = function(startX, startY, endX, endY, strokeStyle, lineWidth) {
if (strokeStyle != null) ctx.strokeStyle = strokeStyle;
Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas 145
if (lineWidth != null) ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
ctx.closePath();
};
Figure 11: Rendering the background, lines, text, and axes text components
of a chart using the HTML5 canvas
Rendering Data
Once the labels and lines are rendered, CanvasChart handles rendering the data points by calling
a function named renderData(). This function handles iterating through the JSON data points and
drawing lines, points, or both depending upon the settings passed to CanvasCharts render() function.
Lines are drawn to connect the different data points through calls to the drawLine() function shown
earlier in Figure 10, while circles are drawn for specific data points by making calls to the 2D contexts arc() function. The circles that are rendered have a radial gradient applied to them using the createRadialGradient() function. The complete renderData function is shown in Figure 12.
Figure 12: Chart data passed into the CanvasChart object in a JSON format
var renderData = function(type) {
var xInc = getXInc();
var prevX = 0,
prevY = 0;
for (var i = 0; i < data.dataPoints.length; i++) {
var pt = data.dataPoints[i];
var ptY = (maxYValue - pt.y) * ratio;
if (ptY < margin.top) ptY = margin.top;
var ptX = (i * xInc) + margin.left;
if (i > 0 && type == renderType.lines) {
//Draw connecting lines
drawLine(ptX, ptY, prevX, prevY, black, 2);
}
146 Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas
if (type == renderType.points) {
var radgrad = ctx.createRadialGradient(ptX, ptY, 8, ptX - 5,
ptY - 5, 0);
radgrad.addColorStop(0, Green);
radgrad.addColorStop(0.9, White);
ctx.beginPath();
ctx.fillStyle = radgrad;
//Render circle
ctx.arc(ptX, ptY, 8, 0, 2 * Math.PI, false)
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = #000;
ctx.stroke();
ctx.closePath();
}
prevX = ptX;
prevY = ptY;
}
};
The renderData function handles iterating through the JSON data points and calling the appropriate
canvas function to render the data. Once the data points are rendered, the chart looks like the image
shown in Figure 13.
Figure 13: The completed chart rendered using the HTML5 canvas
Canvas Insights
You can see that theres a fair amount of JavaScript code required to use the canvas object. However,
once the different API functions are understood, its simply a process of calling the appropriate functions to render lines, text, or shapes. Although the CanvasChart object shown here is only a prototype
at this point, I hope it provides insight into what the HTML5 canvas is capable of rendering and how
some of the features it provides can be used.