Oli.jp

Articles…

HTML5 structure—div, section & article

It seems my HTML5 id/class name cheatsheet article interested a few people, so here’s the start of an in-depth look at the document structures that fall out of the HTML5 spec, using HTML5’s new sectioning elements. These elements are replacements for the common ad-hoc semantics we applied before HTML5 with @class and @id, for example <div class="sidebar"> or <div class="nav">.

Let’s introduce three easily confused elements used to structure a page:

  1. <div> — the generic flow container we all know and love. It’s a block-level element with no additional semantic meaning (W3C:Markup, WhatWG)
  2. <section>a generic document or application section. A <section> normally has a heading (title) and maybe a footer too. It’s a chunk of related content, like a subsection of a long article, a major part of the page (eg the news section on the homepage), or a page in a webapp’s tabbed interface. (W3C:Markup, WhatWG)
  3. <article>an independent part of a document or site. This means it should be able to ‘stand alone’, and still make sense if you encountered it somewhere else (e.g. in an RSS feed). Examples include a weblog article (duh), a forum post or a comment. Like <section> these generally have a header, and maybe a footer (W3C:Markup, WhatWG)

The difference between <div>, <section> and <article> #

In writing POSH HTML we should use the most suitable or semantically accurate element. In HTML4 <div> is a general block-level container element; it doesn’t have any semantic meaning beyond being block-level, and is used when there are no more appropriate elements (i.e. all the time). There is no requirement for the things inside the <div> to be related to each other.

The <section> element #

The new HTML5 <section> element is similar to <div> as a general container element, but it does have some semantic meaning—the things it contains are a logical group of related content:

The section element represents a generic document or application section. A section, in this context, is a thematic grouping of content, typically with a heading.

It is also a ‘sectioning content’ element. Along with <article>, <nav> and <aside>, it indicates a new section in the document. Imagine making your page into a bulleted list of related parts — sectioning elements create a new bullet point in the page’s outline, with indentation reflecting nesting. Note <div> isn’t a sectioning element.

The <article> element #

The new HTML5 <article> element is like a specialised kind of <section>; it has a more specific semantic meaning in that it is an independent, self-contained part of the page. We could use <section>, but using <article> gives more semantic meaning.

Which one to choose? #

To think about HTML4, we can compare this (kind of ;-) to <p> and <blockquote>. Both are block-level elements for text, but <blockquote> is like a subset of <p>, with a more specific meaning (‘this is a block of quoted text’). The same with <section> and <article>; <section> means related content, but <article> means one piece of related content which makes sense on it’s own, even outside the context of the page (the page’s header and footer etc).

The potentially confusing part of this is that <section> can be used for parts of a page (eg the main content column, the news section on a homepage) and contain <article>s, and also for sections of a long <article> (i.e. inside an <article>).

To decide which of these three elements is appropriate, choose the first suitable option:

  1. Would the enclosed content would make sense on it’s own in a feed reader? If so use <article>
  2. Is the enclosed content related? If so use <section>
  3. Finally if there’s no semantic relationship use <div>

Except for occasional use to provide a hook for styles, I expect the humble <div> will mostly be superseded by <section> — and more specialised elements where required — in semantic HTML5.

<section> and <article> are used like <div> is used in HTML4—eg these elements can’t be used inside <blockquote> or <address>. Also avoid nesting an <article> inside another <article> — use <section>s for indicating logical parts of an <article> instead.

Document structures #

Let’s describe some common document structures and convert them to HTML5:

A weblog article #

  • Weblog article
    • Title
    • Content…

In HTML4 we’d probably wrap the article in <div class="article"> etc. Obviously we should use <article> instead in HTML5.

<article>
	<h1>Title</h1>
	<p>Content…</p>
</article>

A long article with subsections (like a thesis) #

  • Article
    • Title
      1. Section
        • Section title
        • Content
      2. Section
        • Section title
        • Content
      3. Section
        • Section title
        • Content

Again the article would generally be wrapped in a <div> in HTML4, and the subsections would only be suggested by <h1>-<h6> elements. In HTML5 the article should be wrapped in <article>, and the subsections of the <article> should be explicitly indicated by wrapping them in <section> elements, perhaps in ordered list items if you’d like section numbering.

<article>
	<h1>Title</h1>
	<section>
		<h2>Section title</h2>
		<p>Content</p>
	</section>
	<section>
		<h2>Section title</h2>
		<p>Content</p>
	</section>
	<section>
		<h2>Section title</h2>
		<p>Content</p>
	</section>
</article>

A weblog homepage #

  • Weblog header
    • Site title
    • Search
    • Site navigation
  • Main content
    1. Weblog article
      • Title
      • Summary
    2. Weblog article
      • Title
      • Summary
    3. Weblog article
      • Title
      • Summary
  • Secondary content
    • Blogroll, photos, other content…
  • Footer

All the main block-level sections of this structure would generally be <div>s in HTML4. Using our pieces from above, in HTML5 the <article>s should all be inside one <section> (for main content), with the secondary content also inside a <section> (or possibly an <aside> — more on those soon). Any independent (‘can stand alone’) chunk of content in the secondary content might also be marked up with an <article>. Note that the semantically dedicated might consider choosing to wrap the list of articles in <ol> list items if they are sorted by date, which articles on weblog homepages normally are :)

<header id="page-header">
	<h1>Site title</h1>
	<form>Search</form>
	<nav class="site-nav">
		<ul>Site navigation</ul>
	</nav>
</header>
<section id="main-content">
	<article>
		<h1>Article title</h1>
		<p>Summary</p>
	</article>
	<article>
		<h1>Article title</h1>
		<p>Summary</p>
	</article>
	<article>
		<h1>Article title</h1>
		<p>Summary</p>
	</article>
</section>
<aside class="sidebar">
	<section>
		<h2>Blogroll…</h2>
	</section>
	<section>
		<h2>Photos…</h2>
	</section>
</aside>
<footer id="page-footer">
	<h2>Footer</h2>
</footer>

As you can see in this code sample <section> and <article> aren’t all the new structural tags! Stay tuned to see what becomes of the header, aside, navigation and footer

Feedback

Questions? Feedback? Mistakes? let me know via Twitter (@boblet). Tweet about it using this shortlink: http://01i.jp/html5s1

Changes #

  1. Added sectioning content link and improved explanation
  2. Improved explanation of nested articles
  3. Feedback link, minor improvements to nested list examples
  4. Added links to some other HTML5 articles I’ve written
  5. Changed from HTML5 to HTML 5 etc
  6. The tide has turned—changed from HTML 5 back to HTML5 etc. Also added anchors to titles (on hover) and fixed a typo or two.
  7. Finally migrated from boblet.tumblr.com, allowing me to walk the walk with HTML5 templates improvements, & CSS3 enrichment too.
  8. Made a bunch of changes, including a new introduction, more subtitles, code samples from the list examples and many minor text improvements.