Simple Life and Good Code

Heading elements (h1-h6) in HTML5

In the past, before HTML5

Before HTML5, only heading elements (h1 - h6) where used to create document’s outline. Level and order (not nesting) in which they appear in the document where main factors. Simply put everything below a heading element until the next heading of the same or higher level was considered as a section with given heading element as a header. If there is a heading element with lower level, it creates a nested/child section.

<h1>Heading 1</h1>
<p>Voluptatem impedit tenetur ut ducimus dolores.</p>
<h2>Heading 2</h2>
<p>Possimus inventore eveniet voluptatem dicta.</p>
<div>
  <h3>Heading 3</h3>
  <p>Ut quos omnis. Nulla unde modi.</p>
  <h2>Heading 4</h2>
  <p>Ipsam exercitationem molestias.</p>
</div>

Above markup creates following outline:

  1. Heading 1
    1. Heading 2
      1. Heading 3
    2. Heading 4

It doesn’t matter that “Heading 3” and “Heading 4” elements are inside the same div element. “Heading 3” is still part of “Heading 2” because that is the order they appear in the document.

Here we can see implicit sections that were created:

Example of implicit sections created by pre HTML5 algorithm.

In the future, with HTML5

HTML5 encourages to not rely on implicit sectioning (based on heading elements alone). Instead, sectioning elements (e.g. article, section, etc) should be used explicitly every time a section is needed. Each section should have only one heading element as a child, that will be used as section header. Level and position of heading element inside sectioning element doesn’t matter. Outline algorithm uses sections layout (nesting) as a base to create document outline.

Previous example in HTML5 looks like this.

<article>
	<h1>Heading 1</h1>
	<p>Unde sint vero sapiente odio.</p>
	<section>
		<p>Itaque id amet maiores recusandae velit deserunt.</p>
		<h1>Heading 2</h1>
		<section>
			<h1>Heading 3</h1>
			<p>Maxime blanditiis repudiandae.</p>
		</section>
	</section>
	<section>
		<h1>Heading 4</h1>
		<p>Neque non ipsum pariatur placeat quae.</p>
	</section>
</article>

Level of heading elements doesn’t matter so they all can be h1. “Heading 2” can appear after paragraph in a section and it also doesn’t matter. It creates exactly the same outline as in the first example.

  1. Heading 1
    1. Heading 2
      1. Heading 3
    2. Heading 4

Sections looks exactly the same too, but this time they are explicit and match DOM structure.

Example of explicit sections created by HTML5 algorithm.

There are few nice implications that were already mentioned along the line.

  • Level of heading elements doesn’t matter so we can stop counting and use one level everywhere. We are free to move sections around without worrying about levels getting out of sync.
  • Order in which heading element appears inside section doesn’t matter so we are free to put it where it should be. It doesn’t need to be first.
  • In theory we can have infinitely deep outline. We are not constrained by h1-h6 tags.
  • Because all sections are explicit it is much easier to understand page’s outline based on DOM structure.

Right now, in transition to HTML5

There is a big “but”.

Warning! There are currently no known implementations of the outline algorithm in graphical browsers or assistive technology user agents, although the algorithm is implemented in other software such as conformance checkers. Therefore the outline algorithm cannot be relied upon to convey document structure to users. Authors are advised to use heading rank (h1-h6) to convey document structure.
https://www.w3.org/TR/2014/REC-html5-20141028/sections.html#outlines

It basically means that HTML5 way isn’t supported yet by most browsers 😢 So what can we do? I think the right answer is to combine both approaches and be ready for new HTML5 world and still support older implementation in foreseeable future. In practice it means that we use sectioning elements to create explicit sections in the document and we pick proper level for heading elements inside those sections (and heading element must be fist in the section). Unfortunately it also means that we lose almost all improvements mentioned in previous section.

The final markup

<article>
	<h1>Heading 1</h1>
	<p>Voluptatem voluptas doloribus omnis quis laudantium.</p>
	<section>
		<h2>Heading 2</h2>
		<p>Nesciunt ut necessitatibus delectus nostrum amet error sed.</p>
		<section>
			<h3>Heading 3</h3>
			<p>Asperiores in expedita et rerum nulla voluptatem.</p>
		</section>
	</section>
	<section>
		<h2>Heading 4</h2>
		<p>Incidunt perspiciatis corrupti repellat quasi aspernatur.</p>
	</section>
</article>;
  1. Heading 1
    1. Heading 2
      1. Heading 3
    2. Heading 4

Implicit and explicit sections will also by more or less the same.

Example of sections for both HTML5 and pre HTML5 algorithm.