[whatwg] The real issue with HTML5's sectioning model (was: "Headings and sections, role of H2-H6" and "Should default styles for h1-h6 match the outlining algorithm?")

Eduard Pascual herenvardo at gmail.com
Fri Apr 30 16:37:04 PDT 2010

On Fri, Apr 30, 2010 at 10:56 PM, Greg Houston
<gregory.houston at gmail.com> wrote:
> On Fri, Apr 30, 2010 at 3:04 PM, Nikita Popov <privat at ni-po.com> wrote:
>> On 30.04.2010 21:47, Greg Houston wrote:
>>> <section class="section">
>>> <nav class="section">
>>> <aside class="section">
>>> <article class="section">
>>> <address class="section">
>> I think this defeats all the purpose of the different sectioning elements.
>> They want to save code, not let you state the obvious by class="section"
> "class" has one more character than "kind" or "type" so you are not
> saving much on code here.
> In the CSS, Eduard's proposal requires many more characters for the
> same thing. Compare:
> article
> to:
> section[kind=article]
> or:
> section[type=article]
It's not a matter of saving a few characters here and there. It is a
matter of a deep design issue that triggers surface problems on
several fronts, selection and styling being just one of them. Others
are forward compatibility, and leaving out some legitimate use cases
(like the "See also" example case I mentioned).
Still, if the amount of characters needed for styling is an issue to
you, try to style the headings applying good practice (the <h1>-only
approach), and suddenly you won't be counting the difference in chars,
but in dozens or *hundreds* of selectors (for long and/or complex
documents, it can get to the thousands). Not to speak about the
error-proneness :P

But since you mentioned classes, why not something like this?
<section> stays the same (it's the "fallback" sectioning element for
when no specific element exists)
<section class="article">
<section class="whatever">
In theory, this is blatantly perfect: it uses @class exactly the way
it was intended to be used; it already works on current browsers
(besides IE's silliness with unknown elements, that gets worked around
with a JS one-liner anyway); it degrades quite gracefully, and it
keeps all doors open for future additions.
The *only* issue with that (and the reason I didn't propose that) is a
purely practical one: the outlining algorithm does special-casing with
some kinds of sections (I don't know all the inner details, but last
time I checked it defined site-wide headings based on <article>s).
This may clash with over a decade of using @class as a mere CSS hook,
despite its purpose, on a vast amount of existing content.

> In my example you can still style section without having to overwrite
> it for every kind or type of section. With Eduards you would need
> something like this:
> section[type=section]
I don't know what use do you intend for <section>, but as defined by
HTML 5: "The section element represents a *generic* section of a
document or application." (emphasis added). <section type="section">
is simply pointless: either use <section>, as generic as it gets, or
give it an actual type. On the styling aspect, I'll tell you a magic
word about CSS: specificity. Take a look at this:

section {
    /* Adds a default border (medium width, solid style, gray color)
for all sections. */
    border-top: none;
    border-left: none;
    border-bottom: medium solid #808080;
    border-right: medium solid #808080;
section[type=article] {
    /* Replaces the border color for articles to red. */
    border-color: red;
section[type=nav] {
    /* Navigation sections will have a blue border. */
    border-color: blue;
section[type=aside] {
    /* And asides will have a yellow one. */
    border-color: yellow;
The above works because the "typed" selectors have greater specificity
than the generic one, so their declarations override less specific
rules. But for properties that are not overridden, the generic value
is used.
Now, try to do that with the current sectioning model. To add borders
to all sections, you will need to list all the sectioning elements on
the first block. Which means (in addition to extra typing) that if you
miss any of the elements, you get no border.
Oh, and even if you get things right, try to apply this kind of
borders (or shadows, or any kind of per-section decoration) to a "See
also" section (see my previous messages in this thread): by default,
you'd end up with a double border; and you would need to hack it away
(adding classes or IDs for the selectors to hook in, inline styles, or
even worse approaches).
Still, if you want to specifically select generic sections, the
correct way would be
section:not([type]), section[type=""] { ... }
(you could omit the second selector if you can be sure that your
document won't contain sections with an empty @type).

The awful way HTML5's sectioning interacts with CSS's cascade (one of
the most controversial, less understood, and most powerful features of
CSS) is quite another symptom of the underlying issue.

>> I think introducing pseudo-elements that actually do not exist is a step in
>> the wrong direction. It tries to solve a side effect of the problem, instead
>> of solcing the problem at it's root.
> Again, "sectional" is a not a very good name, but think of it as like
> the "*". Where "*" refers to all elements, "sectional" would refer to
> a particular subset (elements that are considered types of sections).
> Some character could be used instead of "sectional" or another name.
What you are describing would be a pseudo-class, and should have a
syntax like :sectional (I'd rather suggest :sectioning, for
consistency with the terminology used on other places, but besides
that your choice of a name is not too bad). Using a special character
or treating it as a nonexistent element would be awful (harder for UAs
to parse, harder for authors to learn).

> From what I can tell that is basically all that is needed, is some
> selector for different sorts of sections.
Well, I'm not sure what you are aiming to solve with that suggestion,
but there are many issues arising from the sectioning model and this
definitely doesn't solve all of them.

The very purpose of <section> and its friends is to implement explicit
sectioning on HTML, so there is no need to rely on error-prone,
painful-to-maintain implicit <h1-6>-based sectioning. However, the
spec recommends still using <h1-6> anyway, to ensure backwards
compatibility. The compatibility goal itself is a quite good thing
but, on this case, it not only destroys the primary purpose of the
feature, but makes things even worse: having to state the same thing
(the sectioning of the document) twice (with the sectioning elements
and with the numbered headings) doubles the chance to introduce
errors, and doubles the effort required to maintain the content.
To top things up, the current model perpetuates the issue: any
addition (such as the <attachment> example) on a future version of
HTML will trigger the same problems again (maybe softened if CSS's
:any() is already a reality by then, but still it will take extra work
to begin using the new kind of section, and the issue of UAs producing
wrong outlines would still be there).

In summary: the <section>+attribute approach solves all the issues the
current model solves; provides better (backward and forward)
compatibility; allows better leveraging existing technologies (such as
CSS) to work with it; would be simpler to specify and to implement,
and easier for authors to learn; and solves some use cases the current
model does not.

More information about the whatwg mailing list