fromMarch 2012

Drupal 7 Meet 2012's HTML5


All hail the amazing new HTML5!!! (TA-DA!) Okay, before we get overwhelmed by the hype, let's assess.

With HTML5 we have a better tool to describe a page and, as an added bonus, we get better themes, cleaner markup, and—with a bit of forward thinking—enhanced page accessibility.

But the jump to HTML5 is currently filled with a lot of uncertainty and, of course, the usual buzz and talk of it being "the flash-killer." With this comes tags added, removed, and added again: all the fun that a Drupal front-end developer is looking forward to—right?

Those of us who've been around long enough can remember when the jump was made from table-based layouts to the shiny new "semantic" <div> and CSS layouts. It was out with the old (tables and <font size="-1">) and in with the new (<div class="foo"><div class="inner-foo">$bar and CSS.) It was a nightmare: the Browser Wars were still raging, web standards were not even close, and a ton of obscure browser bugs made it hell to work with (the double-margin bug, anyone?) Back then, the jump was massive, a total paradigm shift -- It changed how a web page was described, how it was written, and how it behaved.

Now we are at another sea-change, from XHTML to HTML5. The good news this time is that it is basically just small adjustments to the markup and will open up a lot of new possibilities for the web as a whole.

In the last few years, the drumbeat for HTML5 has been deafening; and all the talk has been a barrage of HTML5, CSS3, Responsive Design, etc. It took over where the web2.0 hype left off.

Before the hype-wagon switches to apps, you can actually start to create shiny new HTML5 sites easily and, at the same time, get cozy with the new coding style—without burning bridges to your old Drupal themes!

Best practices are now slowly taking root and there is great work being done with the upcoming Drupal 8 release. But D8 is not going to be out-the-door anytime soon, so instead of waiting for the magic Drupal8HTML5(CSS3) version to come roaring in, you can upgrade your theme and become an HTML5 hero today!

Relax, it's just <markup>

Let us begin by clarifying that HTML5 is just a language, like, let's say, Danish(!) If you are a Swede (hey, Dolph and Björn) or Norwegian (hey, Opera), you all have the same language roots, but speak a different dialect of that Old Norse language.

As with any language, the more you speak it, the better you get. The same is true for HTML5—the jump from XHTML to HTML5 is easy, as long as you don't try to understand it all at once; begin by learning a few new pronunciations and practicing some simple sentences. On the other hand, if you don't know any HTML, you might as well jump on board with HTML5.

HTML5 is easy going: if you happen to make a mistake, your page will not be burned down by angry Vikings. Stick to good old <div id="header"> -- you won't be axed if you use the strict way of writing markup that XHTML has taught you since Day One.

HTML5, the Plan

Page Layout
Enough folderol. Let's get a theme up using this shiny new HTML5 thingie.

We are going to build a basic theme for a site, with book nodes and comments. Plain, simple, and perfect for getting your feet wet with some of the exciting new features HTML5 brings us.

Pseudo Markup


<!DOCTYPE html>


<header role="banner">
  $logo ...
  <nav role="navigation">
    $menu ...
<div role="main">




    <aside id="comments">










<footer role="contentinfo">



<DOCTYPE! html>

First things first -- let's get the page into HTML5 mode:

Copy the html.tpl.php file out of Drupal core and add it to your theme. You can find the html.tpl.php file in modules/system/html.tpl.php. Copy it and drop it into your theme folder (themes/mytheme/html.tpl.php).

The first line (after all the nice documentation) tells us that this is an XHTML document and the language we're using is plus RDFa information and language:

  "<a href="">
<html</a> xmlns="<a href=""">"</a> xml:lang="<?php print $language->language; ?>" version="XHTML+RDFa 1.0" dir="<?php print $language->dir; ?>"<?php print $rdf_namespaces; ?>>

To convert the good old—not to mention, boring—XHTML doctype and beef it up to the new HTML5 hotness, change the above two lines to:

<!DOCTYPE html>
<html lang="<?php print $language->language; ?>" dir="<?php print $language->dir; ?>"
<?php print $rdf_namespaces; ?>>

Voila!, the page is now sizzling hot HTML5. The Gods Of Markup surely have listened: the doctype is readable and easy to remember. (For those that count bytes, it is also a lot shorter -- everybody wins.)

Of course there's more to HTML5 than a simple doctype change, but it pretty much illustrates the new paradigm: easy to read and work with. Now let's introduce the shiny new tags that are designed to make our lives easier, and describe the page content better, while ridding ourselves of div-itis and class-clutter.

The reality is that many people are still confused about how to work with the new tags and what they actually mean (and, of course, whether or not Google will burn the pages), and if the HTML5 code-cops will drop by and arrest you for bad markup.

Just Like in the Good Old Days

When we went from table-based designs to div and classes, it took some time to get used to; it will now take some time for all of us to grow comfortable with the new tags introduced in HTML5, especially since some of the tags aren't even finished yet! The good news is that you can slowly introduce them one by one in your sites without breaking anything—HTML5 is considerably more forgiving than XHTML.

All your old XHTML markup, with its wrapped divs and 3 class names, are still perfectly valid -- you can even go nuts and begin to write the markup in true hacker style: <DiV clAss="LookIcAnBeReAlLyIrRitAtinGtoLookat">. The validator is perfectly okay with that; chances are that your fellow front-end nerds will smack you though. The way HTML5 is designed is not to get in the way of sloppy markup.

As with almost everything else in life, take it one step at a time and get comfortable with the new tags. Soon you'll be juggling <article>, <section>, and <nav> tags like a pro. When in doubt, the page will still validate perfectly if you use a <div class="i-still-use-divs-so-stop-bugging-me-you-pedant">—the page will not explode and burn down just because you didn't use an <aside> or <section>.

Well that's almost true. IE7 & IE8 are still a special pain, but by including the HTML5shiv, IE will also behave and render the new tags as if they were the good old div's.

Header and Footer (page.tpl.php)

The first two really new tags we are going to look at are the <header> and <footer> tags. Both actually look pretty familiar if you are used to Drupal themes.

Let's look at <header>, which by the w3c represents the "header" of a document or section of a document. That sounds pretty much like the <div id="header"> ... </div>, so let's change that right away to <header>....</header>.

While we're at it, let's do the same with <div id="footer"> and change it to the HTML5 equivalent: <footer>.

Wow, that was easy! Both the <footer> and the <header> fit perfectly into our html.tpl.php, but they can also be used inside any other element (with the exception of the <article> tag which we will look at later). In XHTML, we add an id or class to both the footer and header, but let's add a little accessibility and use the ARIA roles instead, which will add value to the markup and give us two specific pieces to work with in the CSS:

<header role="banner">
<footer role="contentinfo">


  /*all that we used to add in the #header*/

  /*all that we used to add in the #footer*/

Menus: <nav>

It would probably not shock anyone if we added a menu to the header. Menus in Drupal have usually been implemented by <ul><li> and were wrapped in a <div> with a class that took the name from the module that created it. This is why it's not an easy task for a screen-reader to figure out, when there is an actual menu present.

In HTML5, we have the <nav> tag -- which fits perfectly with Drupal's menus. To make sure we wrap our menus in a <nav> instead of the <div>
, duplicate block.tpl and rename it to "block—menu.tpl.php". Remember to clean the cache to make Drupal register the new template file, otherwise nothing will happen. Now let's look at the markup in block—menu.tpl:

Change the outer <div> to a <nav>

<nav class="$classes" role="navigation">

Adding roles, adding more value to screen-readers, and ensuring they understand that this is a navigation element, the menu block will look something like this:

<nav class="block block-menu-block" role="navigation">.... </nav>

This feels very close to our normal HTML markup, with small changes and a little bit of ARIA love to beef it up.


<div class="sidebar">

Even if both the sidebars and main content divs are perfect, we have no idea what kind of content is going to be in the sidebars, so it's pointless to define them at this time. Anyway, since we have moved away from the meaningless <div>'s, it won't make sense to continue the practice of trying to define them, unless you know exactly what's going to be in the sidebar: Don't worry, the page won't explode and it's perfectly valid!

(Oops, did I just set myself up for a flame-war? Let me know at

Main Content

<div role="main" id="#main-content">

Mark the main part of the page up with the ARIA role 'Main', which tells screen-readers that this is the main place to be; again we are using the general div as a wrapper for a CSS identifier.

Basically, if it takes more than ten minutes, then I will simply use a div instead of a class, just like in the good old days. This is a new dialect of html that, unless your name is Jeremy, we are all pretty new at -- so relax, it's just semantics.
The id #main-content is there for the #skip-links method that is normally called from html.tpl.php

The Article (smells of node.tpl)

Okay, back to the new and shiny: <article>. If you didn't know better, you could almost think that the new tag <article> was created just for our beloved nodes. The w3c standard says "article is a self contained element". Does that sounds familiar? Yep, it screams for the nodes—let's grab the node.tpl.php and change the <div class="..."> to <article role="article">. Simple as that!
Yes the ARIA role is added here so we are repeating: this is an article. If you want to dig into the inner workings of HTML5 & ARIA read

The Footer in an <article>

Now things get a little complicated; no worries, just take a deep breath. A <footer> in the node.tpl is not the physical footer in an article, or laid out as the footer; it has nothing to do with where the element is placed in the design or markup order—it's used in an <article> for footnotes, authors meta data, etc. This is the perfect tag for the $user_picture, $author, $date, etc. They are all connected to the node's content.

Remember the <footer role="contentinfo"> that is used in the page.tpl? Now it is easy to identify the different footers without the hassle of overwriting footer styles.

footer[role="contentinfo"] {
 /*site wide footer */
article footer {
 /* styles for authors, date & other meta from the article */

Time Isn't Dead

The <time> tag is still here (even for the brief week it was out of the spec in the Fall of 2011) and it is—not surprisingly—made for describing the time of the content. If I want to describe my daughter's birthday, I could do it something like this, adding into a context: suddenly, 3 months before <time datetime="2010-02-21 ">Freya was Born, </time> early; well, actually, right on time!

For the node.tpl we are adding in the date:

<time datetime="<?php print date('Y-m-d', $node->created); ?>" ><?php print $date; ?></time>

Images and Words

If a node contains an image, there's a couple of nifty little pieces of markup that can help to describe the image and what it actually contains (besides good old alt=""):

  <img src="//">
  <figcaption> $imgtitle</figcaption>

Clone field.tpl.php and rename it to field—image--node.tpl.php, adding something like the above. Now we have a tpl file for all images that are added as fields. We have a relationship between the image and its $title.

Bear in mind that we do not always want to use a <figure> for an image. (One way to test the use of <figure> is to ask yourself if it would go into an appendix for the site.)

Okay, so now that we have strolled through the first part, the node.tpl looks not that different from how it used to look:

<article class="..." role="article">
  <h2><?php print $title;  ?></h2>
    <?php print $name; ?>
  <time datetime="<?php print date('Y-m-d', $node->created); ?>"><?php print $date; ?></time>
    <?php print render($content);?>

The big change here is actually how the markup makes sense when you look at the individual tags: besides being more readable (it's now a joy to open up firebug and look at the markup), we can remove some of the class-clutter that Drupal has a reputation of carrying around. But I will leave that for another article. (Or check out the mothership theme that is dedicated to extreme makeover of markup & adventures of the seven seas; in the example of node.tpl, one could argue for the removal of the .node class.)

Comments Section in the Article

Next, let's take a look at an exciting part of a node's related content: all the comments for the node. As stated before, an <article> is a "self-proclaimed element", which makes perfect sense if you look at each of the comments of a node.

To emphasize the connection between the node and its comments, we use the <section> to describe this.

.. <h2> comments:</h2>

To get the <section> tag into the comments, you have to copy both the comment-wrapper.tpl and comment.tpl file out from /modules/comments/... to your theme folder. Then change the outer div to an aside, open up the comment-wrapper.tpl.php file. and simply change the div to an aside:

<section id="comments" class="<?php print $classes; ?>"<?php print $attributes; ?>>.

Next up, tell the page that each of your comments are articles: open the comment.tpl file and change the outer div to an <article> and, if you feel adventurous, add in the <footer> tags and a wrapper for the $author, $date, etc., as we did with the node.tpl. When a comment is new in the Drupal world it used to get <span class="new">new</span> added. Let's note that this is a new comment, and mark it up properly:

  <?php if ($new): ?>
    <mark><?php print $new ?></mark>
  <?php endif; ?>

Now the nodes and their comments are nicely described, including the connection between the elements.

Recent Comments Aside Block

Before we conclude, let's look at the "Recent comments" block, and give it another one of the fresh tags that HTML5 provides: <aside>

Copy the block.tpl to a new file and rename it block—comment--recent.tpl.php. Now change the outer div to be an <aside>.

The aside tag is used for "content tangentially related to the content surrounding" ( which fits well with the recent comment blocks.

But It's Changing...?

HTML5 is not yet set in stone. Word from the rumor mill is that the "standard" will be completed in 2014—an eternity in web time. That standard will probably change a lot during the next couple of years, but that is no excuse to procrastinate learning this new dialect of HTML; as you can see from these examples, it's fairly easy to use and very forgiving, even if you make a "mistake" (omg! omg! omg! she used a <b> instead of a <mark>) there's nothing to be afraid of; roll it slowly into your day-to-day work and enjoy all the sweet new things that will be given to you in the next couple of years. My personal favorite these days is the forms placeholder attribute.

It is important to remember that the markup is no longer a senseless use—divs & spans with a class name or two for "theming help". The core concept is that HTML5 markup describes what the content is, which makes sense both for those who write it and for the end-user (especially if you look at a page with a screen reader). Oh, the horror! This means that we can't just fire up a CMS (like Drupal) and mindlessly throw in divs & spans on top of it, with a blind hope that it will make sense. Rather, it demands careful planning of the markup, on every level, from when the content is written to the markup as added for description.

The Markup is the way we describe, for a machine, what the content is and how it relates to each other; at the same time, it's the tool we use to implement design and usability for the end-user. Now we have to be able to both feed the machine and the end-user at the same time. This is not an uncomplicated task, and it can't just be done by throwing in a ton of tags, hoping it will work. Markup is the language of love ;) —making both machines & humans understand what's happening on a page; if we neglect that, we don't understand our own media.


The HTML5 Gang Sign


Why Shift to HTML5

  • It's new and shiny and awesome -- it's the future.
  • CSS3 awesome effects rounded corners animations etc.
  • Form placeholders!
  • Clean markup
  • Better accessibility
  • It's easy to shift over -- you can keep your coding styles from XHTML
  • You don't win by not upgrading

Documentation & When-To's

The Drupal8html5 Initiative

One of the most exciting initiatives for Drupal 8 is getting HTML5 into core. The group is working hard each week to get Drupal core up to speed and ready for the next generation of websites. This calls for a very close look at all the corners of Drupal, and a lot of decision-making for the future of Drupal, both from a clean markup perspective and from the Design implementation. Come join the fun, bi-weekly on IRC #Drupal-html5 Sundays and Tuesdays at 4PM EST.

To follow up on the project, join the group
Or follow the initiative on twitter: @drupal8html5
HTML5 Initiative Roadmap:

Drupal HTML5 Tools

HTML5shiv: Getting IE Up To Speed

<!--[if lt IE 9]>
<script src="//"></script>

Old versions of IE (7+8) don't understand the <nav>, <header>, <aside> etc. add the HTML5shiv to make it play along with the modern browsers.

Suggested Reading


  • HTML5: this is just the markup that will describe the page
  • CSS3: colors, animations, and things that go whoosh on the page
  • Responsive: change the layout based on the size of the screen


Fantastic overview of HTML5 tags and their implication within Drupal's template files. Excellent. Any thoughts on the higher level state of HTML5 within Drupal 7? Re:

I'm wondering if the focus will shift fully to Drupal 8 and D7 will remain with HTML5 integration gaps.