I'm building an HTML snippet that will be dynamically included on a page. The snippet looks something like this:
<article>
<h2>Title</h2>
<p>Content</p>
</article>
The problem is that I have no way of knowing where in the document outline this snippet will be included. It may appear directly under the <h1>
, or it may be nested several levels deep under an <h4>
. In other words, my outline may look like this:
<h1>
<h2>
<h3>
<h2>
<h2>
Pretty logical. Or it may look like this:
<h1>
<h2>
<h2>
<h2>
<h2>
Not so logical. Or it may even look like this:
<h1>
<h2>
<h3>
<h2>
<h2>
<h2>
Downright weird, and I have no way of knowing or controlling it!
I'm not concerned about styling, just semantics.
I'd say the best solution would be to just use <h1>
s everywhere and let sectioning elements handle the semantics per the new HTML5 document outline, but my research has advised me against that because no client actually supports that outlining method. So what is the best solution?
A few ideas have come up in the comments that use scripting to solve the problem. These could work, but I guess I want to know if there is a sensible solution that doesn't require the added complexity of code that does things I think the browser should be doing on its own.
Hypothetically, if such scripting solutions were impossible for whatever reason, would it make sense to create a flat outline using just <h1>
s rather than create a completely wrong outline with improperly nested sub-levels?
As far as the HTML5 spec is concerned, you may use any heading element (h1
-h6
), as long as you always use a sectioning element (like article
).
All of these snippets are valid, they create the same outline, and they are semantically equivalent:
<!-- h1 + h2 -->
<body>
<h1>heading for 'body'</h1>
<article>
<h2>heading for 'article'</h2>
</article>
</body>
<!-- h1 + h1 -->
<body>
<h1>heading for 'body'</h1>
<article>
<h1>heading for 'article'</h1>
</article>
</body>
<!-- h1 + h6 -->
<body>
<h1>heading for 'body'</h1>
<article>
<h6>heading for 'article'</h6>
</article>
</body>
<!-- h5 + h1 -->
<body>
<h5>heading for 'body'</h5>
<article>
<h1>heading for 'article'</h1>
</article>
</body>
Because each sectioning element has not more than one heading in these snippets, the heading elements h1
-h6
work like the (often proposed) h
element: the rank doesn’t matter.
But, like always, some user agents might not follow the spec here, for various reasons. If you want to convey the intended outline to these UAs, too, you would have to rely on the heading element ranks (like it’s the case in HTML 4.01). That’s why the spec recommends to do this:
Authors should use heading rank (
h1
-h6
) to convey document structure.
What to do if calculating the rank isn’t possible? Make the best guess¹ possible, and live with a non-ideal outline for UAs that don’t support the full HTML5 outline algorithm. For UAs that support HTML5’s outline algorithm, it will work fine.
¹ Guesses like:
It never should be a h1
, because your snippet will be a sectioning element, so it starts at least at level 2 in the document (level 1 will always be any heading element with body
as nearest sectioning parent).
Depending on the nature of the snippet, low headings will be very unlikely. For example, if the snippet is a comment form for blog posts, it should be on the same level as the article
element or one level below (if it’s nested inside the article
), so typically h2
or h3
.
If the snippet represents something very important for users, a higher heading should be used, because with a lower heading users that rely on the outline for navigating might never access the snippet’s content, as it could be "hidden" in the deep outline, below entries the users might possibly have no interest in (so they might skip the whole section with all its children).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With