Chapter 2. Upgrading to HTML5

HTML takes a few hours to learn and years of experience and discussion to master. Yes, most software engineers, designers, and even large numbers of high school students claim to know HTML, but they likely know only a few elements, and likely use those few elements incorrectly.

In this chapter, we’re going to cover many of the sectioning elements of HTML5. By the time you’re done reading this chapter, you should have a very good understanding of the semantics of HTML5. I can’t teach you everything about HTML in three chapters. Truthfully, I am still learning HTML—and not just because HTML5 is still an unfinished spec. With the specifications being incomplete, there will likely still be several changes. But don’t worry about that either. Likely, what has been implemented in browsers will stay the same with just some nuanced differences.

I hope that in addition to learning about the various elements, their attributes, their semantic meaning, and their purpose, you take from this an awareness that you know less about HTML than you thought: the more you learn about HTML, the more you realize how much more there is to learn.

We’re going to cover elements, briefly. While a chapter could be written about each element, we do have a lot of ground to cover in a few not-so-short chapters. We’ll cover enough for you to know how to use each element, and for you to at least know what you don’t know.

The first thing to know is that there is no space in the term HTML5: it is HTML5, not HTML 5.

You see? You’ve learned something! You’re already ahead of the game. Let’s dive in.

HTML5 Syntax

HTML5 is very similar to HTML 4 and XHTML. Most of the elements supported in both are still supported in HTML5. Only deprecated tags and attributes have been removed. For the most part, if your document validated as HTML 4 Strict or XHTML, your document will be valid HTML5.[12] The syntaxes of HTML and XHTML are slightly different, but both are supported. Simply change your HTML 4.01 or XHTML doctype to <!DOCTYPE html> and it will validate as HTML5 (more on doctype later).

HTML5 improves upon HTML 4 and XHTML, encompassing the elements of previous versions, removing deprecated elements, adding some new elements, and redefining or fine-tuning yet other elements.

The authors of the HTML5 specifications looked into what developers were already doing on the Web: what document sections all sites tended toward, what classes and IDs they gave those components, what scripts most site authors reiterated, and which library features had proliferated to ubiquity.

HTML5 attempts to handle what individual developers have been doing on their own: creating a standard, detailing how browsers are supposed to handle these standards, and how browsers should handle developer markup when their code is, um, less than standard. The HTML5 specifications detail precisely how browsers are supposed to handle, or interpret, every instance of correct and incorrect code. Through this attention to minutiae, one of the goals of HTML5 is to inform browsers how to handle every possible scenario, so browsers construct identical DOMs from the same markup, and so that developers don’t continue to waste bandwidth dealing with browser differences.

Personally, I would like to see stricter standards. My view is that instead of browsers leniently interpreting bad code, developers should code correctly. You’re reading this, so I assume you’re in the “good code” camp. Good! That’s what you’re going to learn.

A web page is made up of a series of elements. Some elements are empty, other elements contain text, while others contain other elements (or both elements and text). Most elements can contain child elements or text nodes. Those that can’t contain children, such as images and meta elements, are called empty elements.

As shown in Figure 2-1, an element is a construct consisting of an opening tag, some optional (and occasionally required) attributes, usually some content, a closing tag, and, if you’re coding XHTML style, an optional forward slash to self-close the tag for empty elements such as <img> or <input>.

In prior versions of HTML, inline elements could only contain other inline elements and text. Depending on the element, block-level elements could contain other block-level elements, inline elements, and/or text. Their descendant elements, like the ancestor elements, are also made up of elements, attributes, and text.

In HTML5, we’ve said good riddance to the notion of inline versus block elements—naming conventions based on presentation. In HTML5, elements are defined as sectioning, heading, phrase, embedded, flow, metadata, and interactive elements. Semantically, however, some of the ideas remain the same. For example, sectioning elements should not be located inside of phrase elements.

All elements can have attributes. Some elements have required attributes. An example of an attribute is the href attribute of the <a> element, as shown in Figure 2-1. Attributes are typically name/value pairs, with the value optional for Boolean attributes.[13] Attributes provide additional information to the rendering engine about the element, and are found in the opening element tag and not in the closing tag.

There are several attributes that are global to almost all HTML elements—including the core, or global, attributes and the internationalization attributes (covered in the next section)—and others that are more element-specific, which will be described in Chapter 3 when we cover the elements that they are modifying.

Global and Internationalization Attributes

HTML5 has added several internationalization and core attributes that can be applied to almost any element. The id, class, title, style, lang, and dir attributes continue to be supported on all elements. HTML5 adds accesskey, hidden, and tabindex, along with five proposed interactive attributes, contenteditable, contextmenu, spellcheck, draggable, and dropzone, to the list of core attributes. The attributes are discussed next.

In addition to the global attributes, all elements can also have microdata attributes, WIA-ARIA roles and aria- attributes, and custom data attributes, which are your own attributes that are written as data-*, where * is your own creation. The data- prefix was added to HTML5 to allow developers to create attributes that won’t conflict with future versions of HTML. data-* attributes are described in the section . Microdata and ARIA accessibility attributes are described in Chapter 6.

id

The id attribute is a unique identifier. No two elements should have the same id in a single document, and each element can only have up to a single id. In HTML5, id values must be at least one character long and contain no spaces. This differs from previous versions when the value of the id had to begin with a letter in the range A–Z or a–z and could be followed by letters (A–Za–z), digits (0–9), hyphens (-), underscores (_), colons (:), and periods (.).

The id attribute is generally optional. However, it is required for internal page anchoring and inside form elements when implementing explicit labels. Explicit labels are associated with form elements via the label’s for attribute and the form element’s id attribute. Note that the id attribute is not necessary on form elements nested within an implicit label. Labels and the id attribute are discussed in Chapter 4.

The id attribute is also helpful, though perhaps used a little too heavily, as an anchor for targeting with JavaScript. The id attribute, if included, can be used in CSS to target elements. However, due to the high value, or specificity, of the id in the CSS cascade, even though id selectors perform a tinge better, id values should be sparsely used in CSS selectors. We’ll discuss all of that in Chapter 6. Suffice it to say that by the time you finish this book, you’ll understand that you can target any element on a page with CSS3 selectors without the use of id selectors.

The title attribute provides a human-readable description for any element to which it is applied. The title attribute is often implemented as a “tooltip” on some visual browsers, but other browsers, especially mobile browsers, don’t display the title attribute. While screen readers can be set to support the title attribute, most screen readers do not read the title attribute value as a default setting, so the title attribute cannot be relied upon for improving accessibility.

While the title attribute is useful as an attribute for links, images, frames, and multimedia elements, it can come in handy as a method of providing small bits of hidden information that can be displayed based on user interaction. For example, it is possible to extract the content of the title attribute with CSS and create generated content for “tooltip” pop-ups by including the title value as generated content on a ::before or ::after pseudoelement.

While values of the title attribute can be used for nifty tricks for progressive enhancement, due to the inaccessible nature of such a trick, it should not be relied upon for providing important information. And, because the user can access it, only use title if the content of the title is useful and appropriate. If you are adding content to the title attribute to enable your analytics or add codes for use by your JavaScript, don’t! Crafty abuses of the rel and title attributes are no longer necessary (and never were appropriate) with the addition of the custom data attributes, described in the section .

The preceding attributes were global, or core, attributes in previous versions of (X)HTML, and continue to be. There are also two accessibility attributes supported on interactive elements that are now global attributes in HTML5. These are covered in the following sections.

The tabindex attribute was included in prior specifications on interactive elements such as links and form elements, allowing the developer to set the sequence by which these element types receive focus. HTML5 has expanded the role of tabindex to include any HTML element.

Many people use mice to navigate through a website, clicking on links and form elements to engage the interactive elements. Others navigate through the page using a keyboard; clicking the Tab key and moving the focus from one interactive element to the next. On nontouch phones, users will navigate through focusable elements in four directions with the navigational or directional pad (D-pad, for short). On smartphones, most users generally touch the links they want to follow or the form elements they want to enter. Once they’ve finished entering data into a form element, many dynamic keyboards provide for a Next button to forward to the next form element. By default, only links and form fields receive focus through this method. The sequence of the current element to the element receiving focus via the right button on the navigation pad, the Next button, or the Tab key is the order of the form elements in the source code, unless the native sequence has been usurped by the tabindex attribute.

In HTML5, the global nature of the tabindex attribute adds focusability to all elements—not just form elements and links. The attribute takes as its value an integer. As the user tabs, the elements with the tabindex attribute will receive focus in sequential order based on the value of the tabindex attribute’s numeric value—for tabindexes that have a positive value.

Don’t use tabindex with positive values unless you are able to provide tabindex values to every interactive element on the page plus have good reason to rearrange the order, plus be certain that you will be able to maintain the correct order through the life of the application. Instead, mark up the page in the correct order. The default tab order is the same as the source order. Rearranging the tab order of a page can be very confusing to the user, and can lead to very bad user experiences. It’s best to lay out the page in an order that makes sense, and never use the tabindex attribute. Using the default tab (and therefore source) generally creates the best user experience.

So, if you’re not supposed to change the order of the page, why has tabindex become a global variable? The tabindex attribute has become global to enable programmatic focus on all elements, including noninteractive elements, generally via JavaScript and/or keyboard focus.

Since we don’t want to actually change the tab or keyboard focus order from the source order of the page, the only values of tabindex should be 0 or −1. The value of tabindex="-1" (any negative value works, but −1 is the convention) can be used for programmatic focus and tabindex="0" for accessibility reasons only, if you want to provide keyboard access to an element other than a link or form element without changing the order of the page.

The accesskey is similar to the tabindex, except instead of navigating the page by tabbing through to the element with the next higher tabindex value in sequential order, the focus moves directly to the element for which the activated access key has been set. Think of it as a keyboard shortcut.

The accesskey attribute’s value creates keyboard shortcuts. For example, <input accesskey="s" name="search" type="text"/> creates a search input box with an accesskey of s. When the user presses on the letter “s,” the focus moves to the search input.

The value of the accesskey attribute is one or more characters separated by a space. Generally, it’s just one character, but the specifications allow for more than one keyboard shortcut for an element. The syntax for the value of accesskey is similar to the class attribute in that the value of this attribute is an ordered set of space-separated tokens. However, here the order matters; tokens beyond the first are considered fallbacks for user agents that can’t support the initial values.

While tabindex and accesskey were originally highly regarded as possible solutions for accessibility concerns, they aren’t the accessibility solution that everyone had hoped for. As mentioned previously, tabindex can create a bad user experience by altering the expected sequence of the focus of the page. Similarly, accesskey can interfere with default behaviors and shortcuts set in the client’s browser.

As of yet, I have found no use for the accesskey on smartphones, but because we’re learning HTML5, I’ve included it here. The accesskey used to be helpful before the advent of smartphones, when navigating websites on tiny old mobile device browsers was a chore.

HTML5 includes several new attributes, including some new global attributes, which are included in this section. We’ll cover some of the new element-specific attributes and values when we discuss the elements to which they relate in the next two chapters.

HTML5 supports the Accessible Rich Internet Applications (ARIA) accessibility module attributes of role and aria-*. ARIA is a separate module, and not part of the HTML5 specifications. With live regions, roles, and ARIA states and properties, WAI-ARIA can help improve the accessibility of dynamically updating content and hijacked elements.

When interacting with rich Internet applications, the user visiting with a screen reader may be having one part of the page read aloud while another part of the page is dynamically updated. ARIA live regions can help indicate to the user that a part of the page—a part that doesn’t currently have focus—has updated. With the arialive values of assertive, polite, or the default off, ARIA provides a way for the site author to interrupt the screen reader to inform the user that part of the page has been updated. Associated attributes include aria-atomic, aria-busy and aria-relevant.

The ARIA role attribute enables the creation of a semantic structure on repurposed elements—for example, elements repurposed into a grid, listbox, menu, menubar, tablist, toolbar, tree, or treegrid can be identified as such—making seemingly nonsemantic markup accessible, usable, and interoperable with assistive technologies. While full support of the new HTML5 elements (see Chapter 3) by screen readers may make some of the ARIA structure roles irrelevant, adding the role values of article, application, banner, complementary, contentinfo, document, form, heading, main, navigation, and search to your pages now can help with screen readers that are supportive of ARIA, but not yet HTML5.

Two notes about roles: (1) once set, a role should not be dynamically changed, since this will confuse the assistive technology, and (2) roles take precedence over element default semantic meaning.

In addition to the role attribute and its many values, ARIA also provides for state and property attributes. There are state attributes aria-disabled, aria-busy, aria-expanded, aria-hidden, and property attributes such as aria-describedby, aria-haspopup, and aria-labelledby, which provide additional information on dynamic widgets and repurposed elements. It is best practice to use the most semantic existing element for the job, but when you must absolutely use a specific element for a nonintended purpose (such as a tree menu), ARIA should be used.

Custom data attributes with data-*

In HTML5, you can create your own attributes. While you could create your own attributes before, your markup would not validate. HTML5 introduces the custom data attributes, where, as an author, you can define the name of the attribute.

Developers have been including invalid attributes and/or abusing the title and rel attributes to provide data for interactivity. Instead of misusing HTML 4 attributes like rel and title, simply create an attribute with the data- prefix, and your code will validate.

For example, in our CubeeDoo game, we want to maintain the position and value of every card so that when we compare them, we can see if the first flipped card matches the second flipped card, and also to maintain state, in conjunction with localStorage, when we pause the game and leave the screen. We could keep track of every card as an array in our JavaScript. Instead, we created the data-position and data-value attributes in our markup, dynamically updating the data-value for each new board setup:

<div id="board" class="level1">
    <div data-value="0" data-position="1">
        <div class="face"></div>
        <div class="back"></div>
    </div>
    <div data-value="0" data-position="2">
        <div class="face"></div>
        <div class="back"></div>
    </div>
    <div data-value="0" data-position="3">
        <div class="face"></div>
        <div class="back"></div>
    </div>
    <div data-value="0" data-position="4">
        <div class="face"></div>
        <div class="back"></div>
    </div>
    ...
    <div data-value="0" data-position="24">
        <div class="face"></div>
        <div class="back"></div>
    </div>
</div>

When the user selects two cards, the data-value values are compared. If they match, we have a match. The data-position attribute enables us to track the location of each card, changing the data-value of the two cards to 0 when matched. We also use the value of the data-value attribute to style the front of the cards using attribute selectors, covered in Chapter 7.

Prior to having the data-* attributes, we may have structured our cards with <div class="..." rel="15" title="4"> or similar. While that title might have validated, it was unhelpful and would even allow people to easily cheat (you can still cheat with an element inspector in this game, but showing a tooltip would have made the game a bit too easy) when hovered on the desktop. The data- prefix has been reserved for this purpose to avoid clashes with future versions of HTML. Custom data attributes are intended to store custom data private to the page or application. The only requirement on these attributes is that they are not used for user-agent extensions like -moz- or -webkit-.

HTML Element/Attribute Syntax

We’ve talked about elements and attributes, but we haven’t discussed how to include them. Syntax is important, so let’s dive in.

To include an element in your web page, you include an opening and closing tag. Opening tags start with a left angle bracket (or less-than sign, <), followed by the element name, followed by the right angle bracket (or greater-than sign, >).

Correct:

<a>
<p>
<div>

Incorrect:

<m> <!-- there is no 'm' element' -->
< div><!-- there can be no space before the element name -->

If there are any attributes, they are included in the opening tag, after the element name, separated by a space. All attributes are name/value pairs. Unlike XHTML, HTML5 Boolean attribute values don’t need to be explicitly declared. The browser defaults to true when a Boolean attribute is present but the value is omitted.

Even though HTML5 does not require it, for ease of legibility and best practices, the attribute should be in all lowercase and the value should be in quotes. Depending on the type of attribute, the value may be case-sensitive.[14]

An attribute can only appear once for each element’s opening tag. While you likely know that, and don’t include an attribute multiple times in elements on purpose, it is a common cause of validation errors, so take this as a friendly reminder.

Correct:

<a href="http://www.standardista.com">
<p class="racket-tailed drongo">
<div id="content">

Valid, but not best practices:

<a href=http://www.yahoo.com>
<!-- best to quote all attribute values -->

Not valid:

<p class="racket-tailed" class="drongo">
 <!-- no duplicated attributes allowed. -->
<p class=Racket-Tailed Drongo>
 <!-- while HTML5 does not require quotes around all attributes, it is 
best practice. And, if there is a space in the attribute value, the 
quotes are required to unambiguously delineate the start and end of 
the attribute's value! -->

To end, or close, the element, you include a left angle bracket and a forward slash, followed by the element name (that matches the element in the opening tag) and a right angle bracket. If the element is an empty element (see the section Self-Closing Elements), you can end the element by adding the optional forward slash immediately before the right angle bracket in the opening tag:

<a href="http://standardista.com/mobile/ch2">Files for this chapter</a>
<p class="racket-tailed drongo">Exotic Asian Bird</p>
<div id="content">. . .</div>

In between the opening and closing tags you put the content of the element, which may include other elements and/or text nodes. Nest your elements correctly! If you include an element as a child of another element, the nested child element must be both opened and closed before the closing tag of the parent element:

<div id="content">
 <p class="files">
  Examples in the <a href="http://standardista.com/mobile">
  online chapter resources</a>
 </p>
</div>

In this example, the <div> element contains everything from the first < to the last >, including the descendant paragraph and anchor element. Notice that the <a> is both opened and closed within the opening and closing <p> tags, and, in turn, the <p> element is both opened and closed within the <div>.

There are several coding rules required for XHTML that were optional or even unsupported in HTML. While HTML5 supports both coding formats, here are some nonrequired best practices:

Use lowercase for markup

In XHTML, the element tags must all be lowercase as must all the attribute names. While HTML5 supports camelCase and everything else, please use all lowercase markup. Nothing in the W3C states that attribute values need to be lowercase, but some, like id, are case-sensitive, so stick to lowercase.

Quote all attributes

In XHTML, all attribute values must be encased in single or double quotes. In HTML5, only attribute values with spaces or special characters are required to be in quotes. Make me happy: quote all attributes.

Close all elements

In XHTML, every opening tag must have a closing tag. Empty elements such as <img/> and <br/> must be self-closing. In HTML5, some tags can be left unclosed. While omitting the closing element reduces the number of characters on a page, it can make your markup harder to read and therefore harder to maintain. Some speakers/blog posts recommend omitting end tags to reduce the number of characters to make smaller files for mobile. The few bytes saved are not worth the risk. Reducing the number of DOM elements will have more of an impact than reducing the number of characters in this way. Make me happy: close all elements.

In terms of trailing slashes to close elements, you can include them or you can omit them. Whichever you choose, however, be consistent.

Nest all elements

All tags must be properly nested: if you start tag <a> and then start, or nest, a <strong>, you must close the </strong> tag before you close the </a> tag. Nest your tags correctly: your markup will render as expected, it will be easier to troubleshoot, and your markup will be valid (plus, you’ll make me happy).

Provide values for all non-Boolean attributes

In XHTML, all attributes must be coded as attribute/value pairs, even Boolean values. The default selected option in XHTML should be written selected="selected". In HTML5, the same can simply be coded as selected. In HTML5, providing values for Boolean attributes is not necessary, since including the attribute property makes a Boolean value true even if the value of the attribute is false in most browsers. Whether you choose to include or not include Boolean values, be consistent with your decision. If you include Boolean values, always include them. If you omit them, always omit them.

Don’t include an empty string, ="", for a Boolean (or even non-Boolean) attribute; rather, always include the value.

Note that the empty string can have unintended consequences, especially when it comes to the form attribute as will see in Chapter 3.

Use the most semantically correct element for the job

In XHTML, elements need to be coded in a semantic manner. Tables and forms cannot be included in paragraphs. Form elements, being phrase elements, need to be contained within a semantic block-level element, such as a paragraph or table cell. Yes, you can use spans and divs to contain everything on your page, but if a header is a header, use an <h1-6> tag.

Elements are the building blocks that make up the Web. Without the content of a site, CSS and JavaScript would have nothing to enhance. But, in reality, for a web page to be valid XHTML it only requires five components:

In other words, the minimum required for a valid HTML5 document using XHTML syntax is:

<!DOCTYPE html>
<html>
  <head>
   <meta charset="utf-8"/>
   <title>Blank Document</title>
  </head>
  <body>
  </body>
</html>

I’ve included the charset <meta> element, which is not required if you have the correct HTTP headings set on your server. If you don’t have control over your server, consider it required as well.

In truth, HTML5 doesn’t even require that many elements for a document to be valid. Browsers implicitly include <html>, <head>, and <body> if omitted. The shortest possible HTML5 document is actually:

<!DOCTYPE html>
<title>blank document</title>

Notice in Figure 2-2 that the browser includes the missing tags. When you omit <html>, <head>, <body>, or closing tags, the browser will render the document correctly, adding the nodes as rendered into the DOM and adding closing tags.

Yes, you can fit an entire HTML5 document inside a 140-character tweet. Just because you can omit what were once three of the only five required elements on a page doesn’t mean you should. For ease of legibility and maintenance, especially by others, pick a coding style and stick with it: preferably code in XHTML-style syntax, and include the five elements.

Let’s look at the five “required” components in greater detail.

The Document Type Declaration, doctype or DTD, informs the browser what markup syntax you are using so that the browser knows what to expect and how to handle it. This is always the first line that should be sent to the browser, with the exception of the XML prologue, if parsing as XML. The previous example uses HTML5’s DTD, which is the shortest, and the point of this book, but there are others as shown in Table 2-1.

While you may have been using an XHTML DTD for 10 years, chances are you still copy and paste it into your documents, because you have yet to memorize it. Me too! After typing the HTML5 doctype once, I’ve never had to look it up again.

All modern mobile browsers support all of the HTML and XHTML DTDs, including the new, shorter HTML5 doctype declaration.

If you’re concerned about how your old code will fare with the new HTML5 doctype, don’t worry.[15] If your web page validated as HTML 4 or XHTML Strict, your markup is valid HTML5. HTML5-supporting browsers should provide for backward compatibility of all previous HTML and XHTML versions, including deprecated elements. However, just because the formerly deprecated elements are supported by the browser doesn’t mean you should use them! While <center> and <font> may render as intended, it doesn’t pass as valid or as good code![16] To ensure consistent, clean, and extensible code, I recommend using XHTML syntax including quoting all attribute values and closing all elements. HTML5 allows for lazy coding practices, but don’t be a lazy coder!

The <html> element

The <html> element is the root element of an HTML document. While it is optional in HTML5, it’s required when using XHTML syntax. HTML 4 transitional does not require the <html> element, and neither does HTML5, but we want to write good, clean, standards-compliant code: so, for all intents and purposes, it is required and is written as shown in Table 2-2.

The <html> element has two children nested in it: <head> and <body>. It’s good practice (but not required) to include the lang attribute in the HTML element.

HTML5 provides for a new attribute on the <html> element. The manifest attribute, when included, takes as its value the URL of the manifest file. Application cache, the manifest file, and offline applications are discussed in Chapter 6.

Some HTML5 script tools like modernizr add classes to the opening <html> element. This is completely legal. With the application cache, modernizr script for feature detection, and a language declaration, my opening <html> tag often looks like this:

<html lang="en" manifest="cache.appcache" class="no-js">

We covered the lang attribute earlier. We’ll cover the manifest attribute in offline and storage in Chapter 6. The no-js class should be included if you are using modernizr[17] to test for native implementation of the various web technologies discussed in this book.

The <head> element

The <head> of the document contains important information that, other than the <title> element, is not displayed directly in the browser window.[18] While the contents of the <head> are generally not displayed, most browsers display the title, which is the only required element for a valid HTML5 document, in the tab or other browser chrome. The other contents of the <head> element inform the browser how to render the page and “speaks” to search engine spiders about the content of the page. In terms of changes between HTML 4 and HTML5, the never used profile attribute of the <head> element is not included in the proposed HTML5 specifications.

<head> is the parent element for the required <title>, and the optional <style>, <script>, <link>, <meta>, and <base> elements.

We’ve added a <title>, but we still have a blank web page. All the content that you want to display on your website needs to be in the body of the page, encompassed in a single <body> element. The <body> is the second and last of the two child elements of the root <html> element.

There are several presentational attributes for the body element that were deprecated in XHTML. HTML5 goes along with that ingenious XHTML tradition: HTML5 has none of the presentational attributes that were in HTML 4, like align, bgcolor, and background and link coloring, since their functions are better handled by CSS. The only attributes you will likely be adding to the <body> element are id and class, and lang and dir if necessary.

When viewing the source of a web page, you’ll often encounter event handlers in the opening <body> tag, such as onload="doSomething();". In general, you should only be adding global attributes, such as class or id, to the opening <body> tag. Event handlers should be in your external JavaScript file, and styling should be in your external CSS file.

Our first, bare-bones HTML5 document could be coded like the following, with the only noticeable differences being the character set (described later) and the document type declaration:

<!DOCTYPE html>
<html>
<meta charset="UTF-8"/>
 <head>
  <title>My First HTML5 Web Page</title>
 </head>
<body>
</body>
</html>

And with those six components (DTD, <html> root, <head>, <meta> character set, <title> element, and the <body> element), we’ve created a web page—a blank web page, but a web page nonetheless. And, with relevant contents in the <title> element, our blank web page is more findable by search engines than many sites on the Web.

As I mentioned earlier, you don’t even need that many elements:

<!DOCTYPE html>
<meta charset="utf-8">
<title> My First HTML5 Web Page </title>
<p> Hello World

While this is a valid HTML5 document, it’s not good practice. By being more explicit in your code, developers that maintain your code later, including yourself, will be better able to grok your code’s original intentions.

The <head> may be the least sexy part of the web page markup, as it’s not visible to the user by default. But just because it’s not sexy doesn’t mean you’re allowed to neglect it. The head of the web document is where you, as a developer, tell the browser how to render your page, and where you can give hints to the printer, the search engine, and parser on how the content should be handled.

In the <head>, you will always find the <title>, but you may also come across <meta>, <base>, <link>, <script>, <style>, <command>, and <noscript> tags.

Here is what a really busy head section could look like:

<head>
<meta charset="UTF-8"/>
<title>Mobile HTML5</title>
<meta name="author" content="Estelle Weyl"/>
<meta name="publisher" content="O'Reilly"/>
<meta name="copyright" content="Copyright 2013"/>
<meta http-equiv="date" content="Mon, 18 Nov 2013 16:15:30 GMT"/>
<meta http-equiv="date-modified"
    content="11/18/2013" scheme="MM/DD/YYYY"/>
<meta name="keywords" content="html5 css3 svg
    border-radius canvas audio iphone android ipad"/>
<meta name="description" content="Moving from desktop to mobile:
    Learning CSS3 and HTML5."/>
<meta name="pagetopic" content="Internet"/>
<meta name="page-type" content="Instruction"/>
<meta name="audience" content="all"/>
<meta name="robots" content="index,follow"/>
<meta name="generator" content="Sublime"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<base href="http://www.standardista.com/"/>
<script src="/js/application.js"></script>
<link rel="apple-touch-icon" href="touch-icon-iphone.png"/>
<link rel="apple-touch-icon" sizes="72x72"
    href="touch-icon-ipad.png"/>
<link rel="apple-touch-icon" sizes="114x114"
    href="touch-icon-iphone4.png"/>
<link href="/css/prettification.css" media="all" rel="stylesheet"/>
<link href="/css/tinylittledevice.css" media="only screen and
    (max-device-width: 480px)" rel="stylesheet"/>
<link href="/css/print.css" media="print" rel="stylesheet"/>
<style>
     p {color: #333333;}
</style>
</head>

That is a verbose header, and yours should never look like this, but you should understand it. So, what does it all mean? Let’s take a look...

The <meta> element allows web developers to include various types of metadata on their pages by specifying a property and a value. There are four attributes specific to <meta>: charset, http-equiv, content, and name.

The first <meta> element we’ll cover is the one you’re likely to use in every HTML5 document you create:

<meta charset="utf-8"/>

You’ve likely been adding:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

to your documents for years, telling the browser to treat the page as HTML and to use the UTF-8 character set in case your server’s HTTP headers are not configured to set the charset.

While the <title> element was supposed to be the first element after the opening <head> tag, we made an exception for the character set declaration, as we wanted to be sure the rendering agent knew which charset to render before characters got rendered. While new to HTML5, this is supported in all major browsers, since browsers have been supporting the erroneously unquoted meta:

<meta http-equiv=Content-Type content=text/html; charset=utf-8>

Note that in this incorrectly written <meta> tag, due to the lack of quotes and the space in the value of the content attribute, the browser sees charset as a separate attribute. This former “error,” supported by all browsers because the error was so prevalent, is now an implemented part of the HTML5 proposed specifications.

You can (and should) serve all your files as UTF-8 from the server. If you’re running Apache, add AddDefaultCharset UTF-8 to your .htaccess file.

With the exception of charset, the type of <meta> tag is defined by the value of either the name or the http-equiv attribute value. Other than charset, each <meta> tag must contain either the name or http-equiv attribute and the content attribute.

Generally, unless you’re trying to generate an HTTP response message header, a <meta> tag has the name attribute and a content attribute, yet the values of both are basically freeform: you create the value for the name and the value for the content. We’ll cover the ubiquitous <meta> types first, and then delve into the more mobile-specific ones.

There are several <meta> tags that are specifically geared to mobile devices. Among them are <meta> tags that tell the browser to take up the entire viewport and disable scaling, and to change the status bar color, which we will cover in the following section.

On the desktop, unless you’ve expanded your browser window size beyond the bounds of your monitor, the viewport size is the size of the browser window. On most mobile devices, the scale of the page can be controlled, but the viewport size remains the same, determined by the size of the device’s screen.[19]

The "viewport" <meta> tag allows us to dictate the logical dimensions and scaling of the browser viewport window on mobile. In CubeeDoo, our web application, we’ve used the following meta tag:

<meta name="viewport"
 content="user-scalable=no, width=device-width, initial-scale=1.0"/>

This viewport <meta> tag is supported on all smartphones and mobile devices, including iOS, Android, webOS, Windows Phone, and Opera Mobile. By setting the viewport width equal to device-width, we’re telling the browser to set the document width to the device width. Duh!

The viewport <meta> tag supports a comma-delimited list of directives allowing us to dictate the width, scale, and height of the browser viewport. You can tell the browser to not allow scaling, or to scale up to a maximum or down to a minimum value.

width=<num>|device-width

Generally, you’ll want to use the key term device-width to set the viewport width to the width of the device, though numeric values are also valid. The default value differs by browser, but is generally around 980. The minimum value is 200, the maximum 10,000.

height=<num>|device-height

Set to device-height, or a value like 480 for an iPhone 4 or older, defines the viewport height. This value is generally omitted in favor of using only width. For reference, the minimum value is 223.

user-scalable=no|yes

Determines whether or not the user can zoom in and out to change the scale of the viewport. Set to yes to allow scaling and no to disallow scaling. The default is yes. Setting to no also prevents scrolling on data entry. User scaling, if allowed, can be limited by the minimum-scale and maximum-scale properties of the viewport <meta>.

initial-scale=<float>

Sets the initial scaling or zoom factor (or multiplier) used for viewing a web page. The default value of 1.0 displays the web page unscaled.

maximum-scale=<float>

Sets the user’s maximum limit for scaling or zooming unless user-scalable is set to no. The maximum value is 10, but can be a float value of 0.25 or larger.

minimum-scale=<float>

Sets the user’s minimum limit for scaling or zooming a web page. The minimum value is 0.25.

The default width rendered by most mobile browsers is 980 px. By setting the width to device-width, the user doesn’t need to zoom in on page load because you served them 980 px width on a 320 px device. We could have set the viewport width to 320 for 320 px instead of device-width, but then it would only work correctly on mobile devices of exactly 320 px width. We are setting the width of the window to the width of the device, which is optimal: it scales the page proportionally to the device without the author having to know the width of the device the user may be using.

However, this isn’t necessarily optimal for all websites, but rather just for mobile sites and mobile web applications. Then, when user-scalable is enabled, the user can zoom in to make the page more legible for those who can’t read small print.

With CubeeDoo, we are creating a mobile game. When playing, the user will be touching the screen. We do not want our users to accidentally scale the page up or down while trying to flip a tile, so we told the browser to make the game the full width of the screen and to not allow scaling. Had we been creating a website instead of an app, we would have allowed user scaling without limits for better usability, which we do in our language picker:

<meta name="viewport" content="user-scalable=yes, 
     width=device-width, initial-scale=1.0"/>

The function of the viewport <meta> tag really is presentation, and was never part of any specifications; rather, it’s a feature initiated by Apple. The specification to convert the functionality from HTML markup to CSS with @viewport is well under way, and is partially supported in IE10.

There are also some mobile vendor-specific values: for example, Google and Apple have created their own meta name/value pairs for integrating with some of their services/APIs. There are three such tags that we have used in our project, which we cover in the following sections.

Almost never used, <base> can be really helpful when it comes to local testing. The <base> element gives a base URL for de-referencing relative URLs. For example, suppose you have a relative image in your code such as <img src="image/drongo.gif" alt="Meandering Racket-Tailed Drongo"/>. By including the <base src="http://RacketTailedDrongo.com"/>, the browser will go to the image directory on the RacketTailedDrongo.com server to find drongo.gif.[20]

The base URL may be overridden by an HTTP header, but it’s generally helpful for local testing. Try saving a file from the Web onto your hard drive. Add a base pointer to the originating server in the <head> of the file. When you open the page locally, the page will likely render correctly on your desktop, even though the file is local and you never downloaded images or changed the path of a file in the body of your page. The syntax is:

 <base href="http://www.mydomain.com"/>

The <link> element gets no credit. It’s a powerful, often included but rarely considered element. The <link> element provides the ability to define relationships among your HTML document and other documents and resources. <link> can be used to control print rendering, to link stylesheets and scripts, to define favicons, or to provide alternative forms of the current document.

We have four link tags in our web application:

<link rel="icon" href="/appleicon.png"/> 1
<link rel="apple-touch-icon" href="/appleicon.png"/>
<link rel="apple-touch-startup-image" href="startup.png"/>
<link rel="stylesheet" href="styles.css"/>
1

Add rel="shortcut icon" for IE, which requires the “shortcut” term when favicon is not named favico.ico or not stored at site root.

The <link> element can include several attributes: href, rel, type, sizes, hreflang, media, and title. The rev and charset attributes have both been removed from <link> in HTML5. Here’s the syntax:

<link href="url to resource" rel="type of relationship" title="title"/>

The rel attribute specifies the named relationship from the current document to the resource specified by the href attribute. Both the rel and href attributes are required.

Of our four <link> tags, the first three are for imagery and the fourth you are likely most familiar with: linking to stylesheets.

The media attribute describes for which media the contents of the link will be included. If not declared, the default is all, indicating that the source described by the href attribute will always be present.

Values used to be fairly limited, with values such as screen for desktops and print for printers, etc. Values for media included: screen, tty, tv, projection, handheld, print, braille, aural, and all. Now you can include @media queries. The media attribute value has been greatly expanded with CSS3. We can now serve up different stylesheets based on more esoteric values of the media property. For example, mobile device flipping and desktop browser resizing will change the screen aspect ratio from portrait to landscape and back again, so you can serve different CSS files when in portrait versus when in landscape mode:

<link rel="stylesheet" media="all and (orientation:portrait)" href="prtrt.css"/>
<link rel="stylesheet" media="all and (orientation:landscape)" href="lndscp.css"/>

The @media queries that are new in CSS3 are acceptable values for the media attribute. Newly accepted key terms in the attribute values include:

  • (min/max)-width: Viewport width

  • (min/max)-height: Viewport height

  • (min/max)-device-width: Screen width

  • (min/max)-device-height: Screen height

  • orientation: Portrait(h>w) | landscape(w>h)

  • (min/max)-aspect-ratio: Width/height

  • (min/max)-device-aspect-ratio: Device-width/height

Several <link> attributes that were in HTML 4 have since been removed from the HTML5 spec, including the coords, shape, urn, target, charset, methods, and rev attributes. Also, the title attribute has special semantics on this element.

The rel attribute specifies the named relationship from the current document to the resource specified by the href attribute. The rel attribute is stated as being optional, but if you don’t include it, your browser will not correctly link the resource to your document. A stylesheet link without rel="stylesheet" will not correctly render any styles: your browser will just download the file and think “Well, that was a waste of bandwidth.” (Yes, browsers can think, and they make fun of us all the time.) Table 2-4 lists some values of the rel attribute along with the value’s definition.

Table 2-4. The rel attribute

rel attribute value

Definition of rel attribute value of link element

stylesheet

The most commonly used value of the rel attribute, informing the browser that the linked file should be used to render the presentation of the current document.

When including stylesheet, type="text/css" is no longer a required attribute/value pair, as text/css is the only type of stylesheet language, and is therefore inferred.

next

The link references the next document in a guided tour or next document in an ordered series. The spec was originally meant to aid in the preloading of the subsequent file, improving user experience.

prev

The link references the previous document in a guided tour or previous document in an ordered series.

index

Index for the document.

help

The link references a document offering help, (e.g., describing the wider context and offering further links to relevant documents). This is aimed at reorienting users who have lost their way.

contents

Links to a document containing a table of contents for the document or site.

alternate

Specifies an alternate version of the document. When used in conjunction with the hreflang attribute, it implies the linked file is a translation of the document. When used in conjunction with the media attribute, it implies a media-specific version, such as for a printer. When combined with stylesheet, it indicates that there is an alternate stylesheet for the user to select.

copyright

References a copyright statement for the document or site.

glossary

A document with definitions of terms used in the current document.

icon

The favicon for the page or website.

apple-touch-icon

Defines which icon is displayed on the user’s screen when a web application is bookmarked and added to the screen.

apple-touch-startup-image

A startup image that is displayed while the web application launches. This is especially useful when your web application is offline. If not included, some browsers will display a screenshot of the web application the last time it was accessed.

Android and iOS both support the apple-touch-icon and apple-touch-startup-image. Windows Phone has tiles instead of icons. To include tile information, include:

<meta name="msapplication-TileColor" content="#<color>"/>
<meta name="msapplication-TileImage" content="<image reference>"/>

The <style> element provides a method for you to add styles to a document. Unlike styles imported via the <link> element, the styles included in the <style> tag in the head of the page are applied to the current page only, and are therefore not natively accessible in the cache for other documents to use. Unlike styles added using the style attribute on an element, which only impact the element on which the attribute is placed until the scoped attribute is supported, styles included within <style> are applicable to the matched selectors in the entire document.

The <style> element used to require the type attribute (generally, type="text/css"). It can be omitted in HTML5, in which case its presence with the value of "text/css" is implied. Like the <link> tag, the <style> accepts the media attribute.

New in HTML5, but not yet supported in any browser, is the scoped attribute. Adding the scoped attribute to the <style> element tells the rendering agent to apply that CSS only within the scope, or section, in which that style is found. This will be useful when creating widgets appearing on sites over which you may have no control, ensuring that the CSS for your widget doesn’t accidentally overwrite the hosting website’s CSS.

The <script> tag allows you to include blocks of JavaScript or link to an external JavaScript (or other script type) file. The type attribute was required in XHTML and was almost always type="text/javascript". In HTML5, the type is assumed to be text/javascript. As long as your script is JavaScript, the type attribute should be omitted. Also, the language attribute has been made obsolete.

When src is included, it may seem like the element is empty, since there is no text between the opening and closing tags. Include a full closing tag anyhow, and do not put any JavaScript between those tags.

Although we are discussing elements within the <head> of the document, the <script> element can be found inside the <body> or <head> of the document, and sometimes (usually, really) the end of the body is the best suited location for the <script> element.

Why? JavaScript is generally parsed immediately when downloaded, halting the download of the document in its tracks until the JavaScript has finished being downloaded, parsed, and executed. This can greatly slow down the perceived download time of the page. For this reason, it is recommended to include scripts toward the end of the document, instead of in the <head>.

Consider your visitors to be non-JavaScript users during the time it takes to download, parse, and execute all the components of your web page. Wouldn’t you prefer them to be looking at some content rather than a blank screen? This is why JavaScript performance and source order matters.

There are two attributes that can alter the order of execution of the JavaScript: the defer and async attributes. Both are Boolean, with async being a new addition in HTML5. async indicates that the script should execute asynchronously, when it becomes available. defer indicates that the script should execute after the document has finished parsing. If neither attribute is present, the JavaScript is parsed when encountered. Both are only valid for external scripts and invalid for inline scripts.

As stated earlier, JavaScript is parsed immediately when encountered (unless async and/or defer are included and supported by the browser). Browsers stop downloading additional elements from the server until the JavaScript is fully downloaded, parsed, and executed. By including the JavaScript at the end of the document instead of the head, the perceived download time is much shorter. When the script is in the <head>, the page “hangs” while it loads and executes the JavaScript. With the <script> in the footer, while it actually takes the exact same amount of time to download and execute the script, the perceived download time is much faster as there is no visible halting in the download.

There is a new solution to the issue of the hanging UI due to slow JavaScript in HTML5. Web workers, described in Chapter 6, enable multiple threads of JavaScript to execute concurrently. Dynamically generating the script tag is another trick to improving performance.



[12] See http://www.w3.org/TR/html5-diff/ for changed elements and attributes, as well as obsolete elements and attributes.

[13] Boolean attributes are attributes that are either true if set or false if not. XHTML examples include readonly="readonly", checked="checked", and disabled="disabled", which in HTML5 can (and should) be written as readonly, checked, or disabled, respectively.

[14] Values defined in the specifications are generally not case-sensitive, but strings that you define, such as IDs and class names, are case-sensitive.

[15] The HTML5 DTD throws older IE desktop browsers into quirks mode.

[16] Obsolete features are listed at http://bit.ly/16t5Z6L.

[17] modernizr is a JavaScript library that feature detects HTML5 and CSS3 browser support in your users’ browsers.

[18] It is possible to display the contents of the <head> to the user with CSS.

[19] On most smaller devices, the browser is automatically fullscreen and not user changeable. On some devices, like the Slate tablet, the browser is resizable.

[20] If you’re wondering why I keep referencing the Racket-tailed Drongo, it’s the bird on the cover of this book.