Semantic HTML

Image by Jackson So.

HTML is a markup language chockfull of elements that developers can build from. However, these elements are not always helpfully named. In the days after web development escaped from the <table> based layouts of old (sadly leaving many email clients behind), it became very common to use <div> elements to construct more modern and complex layouts.

In the strictest terms, <div> is known as the 'Content Division Element', a generic, unopinionated, container element in which to flow content. This has always been really great in some respects, as <div> elements afford a good amount of flexibility to developers in terms of layout options. The issue is that at a glance, code can become difficult to parse if everything sits within a <div>, or nested deep inside a tree of them. This is where Semantic HTML comes in handy.

XKCD: Tags.

HTML5 and Semantic Elements

HTML5 standardised a broader set of elements for describing page regions and content relationships. These elements give browsers and assistive technology useful structure when they match the content they contain. This representative list covers the elements used in the examples below; it is not a complete list of every element introduced with HTML5:

<article><aside><details><figcaption><figure><footer><header><main><mark><nav><section><summary><time>

Even though due to their clear semantic meaning you can probably work out what the majority of these are on first reading, let's go through a few of the main ones in a little detail.


<header> and <nav>

The <header> and <nav> elements are very common elements. The <header> represents introductory content for its nearest page or section. A pagelevel header often contains branding or navigation, but that layout is not part of the element's meaning. The <nav> element identifies a major group of navigation links and does not have to sit inside a header.

The <nav> element identifies a major navigation region. It can contain an <ul> with <li> children; the nav and list elements describe different relationships and do not replace one another.

Use unordered lists when the sequence of navigation items does not carry meaning. Use <ol> only when the sequence itself matters; otherwise, <ul> is appropriate.

Both <header> and <nav> have default block layout in current browsers, but their purpose is semantic rather than visual. Unlike a generic <div>, they describe the relationship of their content. A page can contain more than one <header> or <nav>, but only where the content relationship calls for it. A section does not automatically require either one, and repeated navigation regions should be labelled when their purposes differ.


The <footer> element represents footer information for its nearest page or section; it is not simply the visual opposite of a <header>. It can contain authorship, copyright, related links, or <nav>, but its position at the bottom is a common presentation rather than its semantic definition.


<section>, <figure> and <figcaption>

These elements describe separate relationships. Use <section> for a thematic grouping of content, normally with a heading. Use <figure> for selfcontained content that can be referenced as one unit, such as an image, diagram, code listing, or table. An optional <figcaption> provides that figure's caption. None of these elements requires the others unless the content itself has those relationships.


Planning a platform change?

I help teams make difficult platform work clearer, from architecture decisions and migrations to launch recovery, performance, and search visibility.