A Semantic HTML5 DOM

This is a very flexible DOM for structuring Blog Posts and Web Pages. Here is the Gist if you would like to fork and customize it.

<div class='document' role='document'> 
<section class='header container' role='definition'>
<div class='navigation'>
<div class='frame'>
<header class='logo'>
<h1></h1>
</header>
<nav class='menu' role='directory'>
<ul>
<li>
<a></a>
</li>
</ul>
</nav>
</div>
</div>
</section>
<section class='body container hentry' role='main'>
<div class='heading' role='heading'>
<div class='frame'>
<header>
<hgroup>
<h1 class='entry-title'></h1>
<h2 class='entry-summary'></h2>
</hgroup>
</header>
</div>
</div>
<div class='content'>
<div class='frame'>
<article class='post left' role='article'>
<header class='entry-meta'>
<cite>By Lance Pollard</cite>
<span> |</span>
<time class='updated published' datetime='2010-08-02T20:23:00-07:00'>Monday, August 02</time>
<meter value='5' min='0' max='5' title='rating'>5 stars</meter>
<meter value='1200' title='page-views'>1200 views</meter>
</header>
<div class='entry-content'></div>
<footer class='vcard author'>
<a class='profile' href='http://www.facebook.com/viatropos'>
<img class='photo' src='' />
</a>
<address class='info'>
<a class='url fn n' href='/'>
<span class='given-name'>Lance</span>
<span class='family-name'>Pollard</span>
<span class='nickname'>(viatropos)</span>
</a>
<div class='adr'>
<span class='locality'>Berkeley</span>
<span class='region'>CA</span>
<span class='postal-code'>94704</span>
<span class='country-name'>United States</span>
</div>
</address>
</footer>
<dialog id='comments' role='region'></dialog>
</article>
<aside class='right sidebar' role='complementary'>
<article class='widget search' role='search'>
<h3>Search</h3>
<form id='search-form' method='get' name='search-form'>
<fieldset>
<input id='search' name='search' type='text' value='' />
<input type='submit' value='search' />
</fieldset>
</form>
</article>
</aside>
</div>
</div>
</section>
<section class='footer container' role='contentinfo'>
<aside class='bottombar' role='directory'>
<div class='frame'>
<article class='widget recent-posts'>
<h3>From the blog</h3>
<div></div>
</article>
</div>
</aside>
<footer>
<div class='frame'>
<cite role='note'>
Copyright
</cite>
<nav class='menu' role='navigation'>
<ul>
<li>
<a></a>
</li>
</ul>
</nav>
</div>
</footer>
</section>
</div>

Elements of the HTML5 Blog Post DOM

The above DOM structure allows for a lot of design flexibility. It is divided into 3 main vertical blocks:

  1. Header
  2. Body
  3. Footer

Ideally, those would each be HTML5 tags <header>, <article>, and <footer>, but at this level, there's too much we'd need to stuff into them. If at some point I find out that headers and footers are allowed to be nested, then I will change the top-level <section> tags to header and footer.

Each of those sections are 100% width (or auto width, with the root body 100% width). Then there are two <div> tags nested inside each top-level <section>:

  1. A descriptive sub-section
  2. A frame (or wrapper)

The reasons for nesting two tags inside the root <section> tags are simple, if we have a structure like this:

<section class='body'>
<div class='title'>
<div class='frame'>
<header></header>
</div>
</div>
<div class='content'>
<div class='frame'>
<article></article>
</div>
</div>
</section>

... then <div class='title'> can be 100% width, with a custom background design that stretches across the screen, and <div class='content'> can do the same. Then, being wrapped in <section class='body'>, we know they are part of the same section, that they are the same piece of content. Then, the <header> and <article> tags can be width: 960px and margin: auto thanks to the frame.

What that ends up allowing is:

We can style a section of related content with some styles 100% width, and others bound within a frame. If you did something like the following, which is more what we think we could accomplish with HTML5, that kind of design would not be possible:

<article>
<header></header>
<div class='content'></div>
</article>

My Personal Thoughts on New HTML5 Tags

Personally, I think that the introduction of the HTML5 tags is a mistake. There is no possible way they can cover all possible layout/design permutations and create the "perfect" tags for them. I think tags should only be introduced if they cover a very very clear set of functionality, such as the <video> and <audio> tags. I think the old setup is perfect, that plus video and audio.

Tags are the lower level building blocks of higher level content. Think of it like atoms to molecules, molecules to cells.

Tags are like atoms. There only needs to be enough to handle all the ways to organize content. HTML has done this, everything that has been built today has been built with HTML except video and audio which were flash, which I think should be HTML tags (and the <canvas> tag).

Components are like molecules. Objects that are used very often, such as drop-down lists, text editor, color pickers, etc, are components. They are composed of tags. Widgets are are components, in HTML at least (in Actionscript, I wouldn't say that).

The DOM is a cell. You combine widgets and components and areas into the DOM, just like you combine molecules into cells. You could break this down further, but you get the point.

I bring this up is because <article>, <figure>, <section>, <aside>, <header>, <footer>, <dialog> and <nav> are component-level tags. They are like molecules, but they are being defined as atoms! This is a big mistake. If they introduce these, why not introduce things like <widget>, <advertisement>, <chat>, <reputation>, <tag>, <price> and <note>. Those are equally as common as the above.

The reason they don't have those is because the new HTML5 tags are arbitrary. They can't describe the complexity they were meant to describe. Use <div> instead, and give it any class you want.

Well, still try to see what you can do with the new tags, prove me wrong :). That's why I'm building this HTML5 blog post DOM thing.

The Header Section

The header section is this area from above:

<section class='header container' role='definition'> 
<div class='navigation'>
<div class='frame'>
<header class='logo'>
<h1></h1>
</header>
<nav class='menu' role='directory'>
<ul>
<li>
<a></a>
</li>
</ul>
</nav>
</div>
</div>
</section>

The purpose of the header is to display your logo and the main menu, that's it.

The triple-wrap (.header.navigation.frame) is for proper, consistent, flexible styling. Everything in there is the content. The header section consists of:

  • Logo
  • Main Menu

That's about it. Oh, the most-semantic way to create a menu is an unordered list, with <li><a> inside, you don't need to add anything more that that. Everything else can be done in css.

The <nav> tag and the List, how do they work together?

I wondered this, and now I have a perspective. The <nav> tag is pretty much wherever a list is going to be, <ul> or <ol>. Just wrap the lists with <nav>. It adds an extra level of tags, but hey, maybe this is what they wanted? The HTML5Doctor describes semantic navigation with the <nav> element.

You really don't need to wrap that list, but if you do, wrap it with <nav>.

The Body Section

The body section is this area from above (not the actual body html tag):

<section class='body container hentry' role='main'> 
<div class='heading' role='heading'>
<div class='frame'>
<header>
<hgroup>
<h1 class='entry-title'></h1>
<h2 class='entry-summary'></h2>
</hgroup>
</header>
</div>
</div>
<div class='content'>
<div class='frame'>
<article class='post left' role='article'>
<header class='entry-meta'>
<cite>By Lance Pollard</cite>
<span> |</span>
<time class='updated published' datetime='2010-08-02T20:23:00-07:00'>Monday, August 02</time>
<meter value='5' min='0' max='5' title='rating'>5 stars</meter>
<meter value='1200' title='page-views'>1200 views</meter>
</header>
<div class='entry-content'></div>
<footer class='vcard author'>
<a class='profile' href='http://www.facebook.com/viatropos'>
<img class='photo' src='' />
</a>
<address class='info'>
<a class='url fn n' href='/'>
<span class='given-name'>Lance</span>
<span class='family-name'>Pollard</span>
<span class='nickname'>(viatropos)</span>
</a>
<div class='adr'>
<span class='locality'>Berkeley</span>
<span class='region'>CA</span>
<span class='postal-code'>94704</span>
<span class='country-name'>United States</span>
</div>
</address>
</footer>
<dialog id='comments' role='region'></dialog>
</article>
<aside class='right sidebar' role='complementary'>
<article class='widget search' role='search'>
<h3>Search</h3>
<form id='search-form' method='get' name='search-form'>
<fieldset>
<input id='search' name='search' type='text' value='' />
<input type='submit' value='search' />
</fieldset>
</form>
</article>
</aside>
</div>
</div>
</section>

This is where the bulk of your content goes. I have divided the body section into two main vertical sections: title, and content. The reason for this is so you can create a complete custom, 100% width look for the title, that is distinct from the body, while still semantically saying that the title is associated with the content below, like the image below.

Separate styles for title and content

More on this later...

The Title

So the heading div is for the title. In there are the <header> and <hgroup> HTML5 tags. This is where you place your title and all of that.

The Content

The content section is divided into 2 parts:

  1. Article
  2. Sidebar

These all are bound within the space of <div class='frame'> so we can center them like traditional blog posts.

The Article

The <article class='post'> holds everything related to the blog post or page content associated with this URL, except the title (because we want custom styling):

  1. Content
  2. Metadata
  3. Comments

The Article Metadata

This section (or sections) holds all the details about the post that are useful for search engines:

  1. Publish/Updated date. This should include the <time> tag
  2. Tags. Each tag should be in a link with rel "tag" like this: <a href="/" rel='tag'>tag-name</a>. This is the rel tag microformat. This tells search engines that you have a page dedicated to this tag, and some sites actually look for this information to display tags.
  3. Author. The author of the post. This should use the hCard microformat, and the <address> tag to maximize semanticness :). Sites can actually search your page for a vcard and download it as a business card!
  4. Social Buttons.
  5. Analytics.

That's a lot of rich information for search engines.

The Article Content

Finally, this is the actual content of your post. There's a lot else going on your page as you can see. Write lots of good stuff.

I snuck the hAtom microformat in there, which looks for these classes: entry-title, entry-content, entry-summary, updated, published, author, rel='tag', and rel='bookmark'.

The Comments

Comments should be wrapped in the <dialog> tag. Unfortunately, most of the free comment services like Disqus still use <div> and <table> tags to structure their comments, but you could still wrap them in a <dialog> tag.

If you are constructing the comment DOM, use <article> for each comment.

The Sidebar

To the right (or left, or both) of the content is the <aside class='sidebar'> tag. While aside != sidebar, it's nice to use the <aside> tag as a sidebar.

Widgets

Widgets can each be <article> tags. Articles are not only used for posts. The HTML5 Doctor recommends using the <article> tag for widgets. You can even nest article tags.

Finally, the footer section. The footer section is this area from above:

<section class='footer container' role='contentinfo'> 
<aside class='bottombar' role='directory'>
<div class='frame'>
<article class='widget recent-posts'>
<h3>From the blog</h3>
<div></div>
</article>
</div>
</aside>
<footer>
<div class='frame'>
<cite role='note'>
Copyright
</cite>
<nav class='menu' role='navigation'>
<ul>
<li>
<a></a>
</li>
</ul>
</nav>
</div>
</footer>
</section>

The footer of the DOM is divided into two sections:

  1. The bottom widgets section
  2. The footer itself

Reasons for Structuring the HTML5 DOM Like This

It took a while to come up with this DOM layout pattern. I was doing everything I could to try to remove the need to have any divs define the structure, but in the end, I started having to write to many convoluted CSS tricks to make it look like it should if I didn't use divs. So this is what I've landed on.

First, the whole .frame thing. The frame, other's call it a wrapper, is used to frame the content in a certain space. In this layout, the frame is 960px and centered. The problem was this:

  • I want to style the title and content backgrounds so they looked like they were 100% width...
  • But I want the text itself to be centered and bound within 960px.
  • AND, I want the title and content to be an hentry for the hAtom microformat. In otherwords, if you used XPath to traverse the document, you would know that "oh, I'm at an 'hentry', oh there's the title, there's the content". BUT, at the same time, style 100% width...

The only way to do all of that in a consistent way is to have this structure:

<section class='hentry'>
<div class='title'>
<div class='frame'>
text
</div>
</div>
<div class='content'>
<div class='frame'>
text
</div>
</div>
</section>

...and these styles (div's are automatically 100% width because they are blocks):

.title {
background: red; /* 100% width, red background */
}
.content {
background: yellow; /* 100% width, yellow background */
}
.frame {
width: 960px; /* text content is 960px... */
margin: 0 auto; /* and centered */
}

There are cases where you can reduce the number of DOM elements. First, if a vertical section only has one part to it, then you can ditch the div wrapping the frame, and you end up with this:

<section class='content hentry'>
<div class='frame'>
text
</div>
</section>

With that, you can style .content 100% width, and everything within .frame will be 960 and centered.

The only issue I have with that is consistency. If some sections need the more complex solution with 3 div nesting, then it's less mentally complicated to just build everything like that. It only adds less than 10 DOM elements, but makes your entire DOM have the same structure. That makes it very easy to know what's going on at a glance. Convention over Configuration.

Anyway, hope this is useful too you. Almost done implementing it here.

Cheers.

Resources