Semantic HTML: A Guide to Semantic Markup, Part II

In Part I, I wrote about the problems of using HTML 5’s new semantic elements. Ambiguity in the purposes of old and new elements and a lack of definitive answers as to where elements belong in semantic markup hurt efficiency and created inconsistency. I presented a brief argument in favor of a consistent set of standards, particularly in those situations where an obvious choice doesn’t exist.

In Part II, I’ll describe the semantic markup system I came up with. I’ll also discuss some edge cases or judgement calls I made and explain my rationale. If you’re interested in reading more about my motivation and what I believe is the biggest challenge presented by HTML 5 to writing semantic markup, you can read all about it in the first article. It’s not necessary for this post to make sense, but it might give you a sense of why I made some of these decisions.

Classes of DOM Elements

In my system I have four categories, or classes, of DOM elements. The purpose of these classes is simply to make it easier to reason about the purposes of elements you know about as well as more easily understand new elements as they come to your attention or are introduced into the standard. They are as follows:

Structure (Non-semantic markup)

Structure elements are for layout without semantic meaning. These are elements used for arbitrary groupings of other elements. Use these when you want to apply specific styles to parts of a group of elements without conveying any particular meaning or logical relationship. You would also use these as a reference point for JavaScript or some other code interaction, although there’s a caveat to this I’ll address later on. For instance, you might wrap a part of a navigation menu in a DIV in order to apply a different background color or use a SPAN to change the font of a phrase in a line of text.

Mixed (Semantic markup with layout relevance)

Mixed elements convey semantic meaning but are also structural in nature. They group other elements with the same logical purpose. When writing semantic markup, these can stand at the top organizational level of a schema, as in the case of MAIN. They might contain functionally related elements, such as a NAV, semantically related elements such as a SECTION, or both, as in the case of an ASIDE.

Meaning (Purely semantic markup)

Meaning elements convey semantic information without implying structure. Often these do not themselves contain child elements, although they can as in the prior example of a SPAN. Examples of these elements include IMG, H#, and P. This is where the bulk of your content is going to live. NOTE: when I say that these don’t imply structure, that doesn’t mean their layout on the page isn’t or can’t be determined by CSS. It simply means that the definition of the element itself doesn’t inform its relationship to other elements on the page.


This is a special class for elements used outside of structure or meaning in the layout sense. It’s a catch-all category for things like SCRIPT, META, HEAD, HTML, etc., which either aren’t styled or are technical elements used by the browser.

General Guidelines, or, the Tao of Semantic Markup

In the spirit of the Zen of Python I have a list of guidelines to keep in mind when creating a webpage. These aren’t necessarily in order of importance.

  1. Where there is ambiguity, choose the simplest or most obvious answer and stick with it.
  2. Use the least markup required to express content and layout.
  3. Structure is the relationship between elements, not their location on the page.
  4. Schema is the relationship between types of content, not their structure or layout.
  5. Layout is the visual relationship of elements on the page. It usually mirrors structure, but not always, and never has to.
  6. Style is used to give visual meaning to schema and structure using layout and decoration.
  7. Elements necessary for pure JavaScript functionality should be provided by the script itself.
  8. JavaScript enhancements of existing functionality should not change markup.

If there is one statement that sums up the idea here, it’s this: meaning holds content; mixed describes schema; structure supports style.

A Few Words on Judgement Calls and Edge Cases

In order to make a consistent system that works for me in scenarios I deal with frequently I made several decisions where both options made some logical sense. While I didn’t do this in an arbitrary way, the opposite decisions were sound enough to warrant some discussion. Feel free to make the opposite choice, provided you do so consistently. If you’re not sure, ask yourself if you’d make the same decision in three months.


I choose to put ARTICLEs in the Meaning category. There’s a very sound argument to be made that these are Mixed elements. As an example, imagine a single blog post on a page; this is certainly an ARTICLE. In fact, if the post is long enough the ARTICLE might have SECTIONs. I decided not to classify it as Mixed because, to me, a SECTION describes its own relationship to other elements in a way that an ARTICLE doesn’t.


A SECTION could very well be a Structure element. After all, what’s a DIV but a section of a page? However, I decided to group these with Mixed elements because I believe there’s a semantic meaning inferred with the SECTION that makes it something more than Structure. Conversely, as in the ARTICLE example, SECTION could be a Meaning element, but I opted not to for a few reasons. First, for simplicity’s sake. Second, because I don’t think it’s consistent with the call I made on ARTICLEs. Third, because I think that the purpose you’d use SECTION for in a Meaning context is better served by using other Meaning elements and content signals, e.g. headings, bold-faced or italic fonts, indentation, etc.

H#, especially H1

In the Bad Old Days, H1 was always the first and most important heading text on the page. Some SEO strategies still penalize pages with more than one H1, although that’s fading away. In that context, H1 carries some structure information, which would put it in the Mixed class. More modern usage allows for the H-series to start relative to the containing element, so the first or most important heading in a SECTION or ARTICLE. This is clearly a Meaning sense to me.

When Should I Use…


From personal, embarrassing experience, if you find yourself creating DIVs with classes or IDs like “XXX-section”, that’s a SECTION. SECTIONs are going to define the logical sections of a page, whatever that means to you in the context. You might have a section for news that contains recent posts (which would be ARTICLEs) or you might have a section that houses a set of thumbnails. The important thing to remember is that a SECTION is a DIV with meaning. Think of a SECTION as a folder. You put things in the folder that are related to each other in some way, and you label the folder very easily because that relationship is pretty clear. SECTIONs can be styled for layout just like any other block-level element, making DIVs a little less useful.


Poor old DIVs. There’s still a valuable place for these in a minimalist semantic markup system. Because DIVs have absolutely no semantic meaning you can think of them as SECTIONs without the baggage. DIVs are now free from column or row duty, thanks to semantic containers, Flexbox, and Grid. You can use DIVs when you need to fence off elements without implying any semantic meaning to the separation, such as for aesthetic or design purposes. DIVs will still be very useful when you need to absolutely position a child in a relatively positioned container, for example.


Bruce Lawson wrote an excellent article for Smashing Magazine where he makes a compelling argument that, for a number of reasons, the ARTICLE is both semantically and technically correct for most usages and SECTIONs should be ignored or used more or less like DIVs. I agree with about 75% of what he says. ARTICLEs should be used for, well, articles, and, per the W3C standard, discrete compositions which are self-contained and could be reused elsewhere in the document or in syndication. This last bit is where I diverge from Lawson’s take. He makes the perfectly reasonable argument that there are accessibility benefits offered by the ARTICLE element and that due to the way all browsers currently render HTML 5 the SECTION element doesn’t mean anything in the document outline algorithm, because the latter isn’t actually implemented anywhere yet.

The way I see it, however, this applies more to having SECTIONs within ARTICLES, and is mainly pertinent to assistive technology like screen readers. And, honestly, the idea of using ARTICLE to house a “widget” or any other discrete item–not just an article in the conventional sense–may be technically correct according to the spec but feels very much like a hack or a technicality and not at all semantic in a meaningful sense of the word. In my opinion, this is a situation where a DIV would be more appropriate. Lawson focuses on the importance of semantic HTML for assistive technology, but I believe that the most important audience for semantic markup is developers. Most users will see what is visually displayed on the page, and screen readers will obey aria tags (which we should be using anyway), and all of this depends on developers who can look at markup and understand it easily.


There are two competing document outline algorithms, both of which remain mainly theoretical: heading-based and nesting-based. In essence, we’re talking about the size and relative importance of the heading in a given sectional element, such as a SECTION or ARTICLE. One spec, the old familiar heading-based standard, ranks H# elements based on their number (1-6) which is assigned based on the heading’s importance in the document. The rule of thumb is that there should only be a single H1 because it’s the absolute most important heading on the page.

The other spec is based on nesting, and in this case the size and importance of the heading is based almost entirely on its position within the containing sectioning element. In this spec, which is newer and becoming more popular, H1 is simply the first heading in the SECTION or ARTICLE, for instance. And, in theory, browsers will support this when the spec is adopted–which it currently is not–by treating an H1 nested one level inside the document outline (see above) as an H2 for size and importance, i.e. screen reader, purposes.

My choice is to follow the nesting spec because it makes more semantic sense to me. It’s true that the document outline algorithm spec isn’t implemented yet, but, again, this is a situation where the more semantically-valid option is also the one that makes markup easiest to read and understand for developers and designers. If H1 means the first heading in a sectioning element, then you can style various sizes much more easily by referring to the containing element as the parent and walking down through the H# elements. And you can do this without knowing about any other content on the screen.

This brings us to the end of my guide to semantic markup. I hope you’ve found at least some of this useful. Please feel free to reach out in the comments with any additions or feedback. I consider this a living document, and I plan on adding to it as I continue to work on this system and see results from actual use, so check back from time to time.

Note: The savvy reader might notice that this page and, in fact, this site, is emphatically not semantic. That’s because it’s a WordPress blog using the Argent theme, which is a great example of the kind of awful markup I’d love to see web development move away from. I’m currently working on replacing WordPress with Wagtail; read more about Wagtail here.

Leave a Reply

Your email address will not be published. Required fields are marked *