Many web developers new to HTML5 initially ask the question, What are the new tags or elements in HTML5? Some of the new elements (e.g., <video>, <audio>, <canvas>) provide an immediate, beneficial effect on the user experience (UX) when they are rendered in a browser. Yet many of the new elements, called semantic elements and listed in Figure 1, have no visual impact whatsoever on UX. What are these elements, and why should you care about them?

Figure 1: HTML5 semantic elements

Element

Level

Purpose

<article>

Block

Independent content, such as a blog post or article

<aside>

Block

Content slightly related to primary content on page

<figure>

Block

For grouping standalone content, such as video or image

<figcaption>

Text

For use with <figure>, (optionally) used to provide caption

<footer>

Block

Providing data such as author, copyright

<header>

Block

Introductory headings; could include navigation

<hgroup>

Block

For grouping <h1> to <h6>

<nav>

Block

Navigation—typically site-level

<mark>

Text

Text to be referenced or highlighted

<section>

Block

Grouping of content usually with a heading, similar to chapters

<time>

Text

For date and/or time representation

In a previous article in this series, "Three of the Most Important Basic Elements in HTML5," 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.

Examining a Typical HTML Template

To demonstrate the "how and why" of semantics, let's consider how you could use HTML5 semantic elements to upgrade the default template of an ASP.NET MVC 3 Razor website in Visual Studio 2010. (Our example assumes that Visual Studio 2010 SP1 has been installed, as well as the Web Standards Update.) To follow along, simply create a new website in Visual Studio 2010 and choose ASP.NET Web Site (Razor), as shown in Figure 2. Note that although the example website in this article is based on ASP.NET, it will demonstrate aspects of semantic elements that you can apply to your own website development.

Creating a new ASP.NET Razor website

The resulting files produced when creating an ASP.NET website using Razor syntax include a file named _SiteLayout.cshtml (or .vbhtml, for a site created using Visual Basic). This file is used as a template, so that other pages can focus more on the main content of the page. Take a look at the overall markup (minus the contents of the <body> element) of this HTML5 document, shown in Figure 3.

Figure 3: Overall markup of _SiteLayout.shtml
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
BEGIN CALLOUT A
        <title>@Page.Title</title>
END CALLOUT A
        <link href="@Href("~/Styles/Site.css")" rel="stylesheet" />
        <link href="@Href("~/favicon.ico")" rel="shortcut icon"
                type="image/x-icon" />
    </head>
    <body>
        <!-- see figure 4 -->
    </body>
</html>

The content in the <title> element in callout A contains the following syntax:

@Page.Title

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 &lt;body&gt; tags of _SiteLayout.shtml
<div id="page">
  <div id="header">
BEGIN CALLOUT A
    <p class="site-title">HTML5 Demo Site</p>
END CALLOUT A
    <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.Title</h2>
      @RenderBody()
    </div>
BEGN CALLOUT B
    <div id="footer">&copy; @DateTime.Now.Year, Don't steal me...</div>
END CALLOUT B
  </div>
</div>

Note the <div> with an id of "content" in Figure 4, which contains the following syntax:

<h1>@Page.Title</h1>
<h2>@Page.Subtitle</h2>
@RenderBody()

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>

To support the modifications to the initial files of the website, the site.css file has been updated to contain additional style rules, as Figure 6 shows.

Figure 6: Style rule changes to site.css
/* all ul#menu replaced with #menu */
h2
{
    padding-top: 0;
    margin-top: 0;
    font-size: 1.3em;
    color: #5c87b2;
}
img
{
    display: block;
    float: next;
}
#sidenote
{
    width: 330px;
    border: 1px dashed #990000;
    padding: 5px;
    float: next;
}
#sidenote h1
{
    font-size: 1.2em;
    color: #990000;
}
section h1
{
    font-size: 1.1em;
}
nav h1
{
    display: none;
}
#logo
{
    float: right;
}
.definition
{
    font-style: italic;
    background-color: #e8eef4;
}

When the default.cshtml file is requested and rendered, it will appear as shown in Figure 7.

Default.cshtml rendered in a browser

At this point, none of the new semantics elements have been introduced, but the scene has been set for showcasing how and why we will use them.

To <div> or not to <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:

#page
{
    width: 90%;
    margin-left: auto;
    margin-right: auto;
}

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: What really 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.

Example HTML5 source outline

There are several logical problems in the resulting outline:

  1. The site's header is ignored.
  2. The subtitle supports the title; it should not be its own section.
  3. The "side note" of the page is given too much importance.

We will solve all these problems by using semantic elements.

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. The site-level heading now appears, and the subtitle has disappeared! Notice that despite multiple <h1> elements, there is correct indentation between the first two.

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 re-engineer 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.

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">
  &copy;
  <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 the above 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.

The Final Section

The co-author of this series, Daniel Egan, and I are often asked by those new to HTML5 when to use the <section> element. It is our opinion that this element has the potential to be the most misused or unused of the semantic elements. In our example, our "article" is rather small. The larger an article, the more likely it will be divided into manageable "sections" (as is the case with the article you are reading). You can use the HTML5 Semantic Notepad tool as an aid in visualizing the <section> as well as other semantic elements in an HTML5 document, as shown in 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 &lt;section&gt; element to an HTML5 document
<section>
    <h1>A list of semantic elements</h1>
    <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>
</section>

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.

Example HTML5 source outline after final set of code modifications

Make HTML Code More Meaningful

Semantic tags may not impact your users visually, but they provide meaningful data to modern parsers and search engines—so they can potentially have significant impact on your site's search-engine ranking and web traffic. I've shown you how, with a few adjustments, you can start using semantic elements now in your own websites. Get accustomed to using these new elements now—you'll be glad you did! In the next two articles of this HTML5 series, Dev Pro contributing author Dan Wahlin will show you how to effectively structure JavaScript code in HTML5 applications.