Last weekend, I set out to write a posting for this site. In the course of working on that, I ran into this old problem again, and got absorbed in trying to solve it. I'd had some ideas on it a couple of years ago, but had never gotten around to trying them out. The result is this posting instead of the one I had originally intended to write. I'll still get to that post later....
We've been told for some time now that we shouldn't use HTML tags to directly format content. Instead, we're supposed to be using tags as delimiters for different kinds of content, and we're then supposed to use those delimiting tags to format content via CSS selectors. The notion is that tags are a form of semantic markup, and that we're using this technique to keep content separate from presentation. (If you're not familiar with this concept, you can get a feeling for it by visiting the CSS Zen Garden.)
The theory is good: you should be able to use CSS to reskin content on your site in any way. I once worked on a large media publishing system which would capitalize on this by making news available in the form of pure NewsML, thereby allowing various properties to format it to suit the look and feel of their pages.
Textbook-style content is broken down into sections. Sections can have sub-sections, which can in turn have more sub-sections. Here are some examples:
- CSS Zen Garden
The page has a number of sections separated by section headings.
The page has several sections, again separated by headings.
- The Golden Rule of Pointers
A page from this site which demonstrates the same general structure again.
These examples aren't using nested sections, but I've run into a number of cases where I wanted to do that. I've done it on this page to demonstrate the effect.
I tend to write a lot of wiki documentation for projects I'm working on, and I like to use the textbook style described above. This documentation is hand-crafted in the target wiki. The sections are helpful because they delineate concepts in a useful way, and I make the section headings named anchors so that I can send people links to them.
HTML provides what I'll call the heading tags: <h1>-<h6>.
These appear to be what I need to use to achieve this effect. Each section is headed by one of these. However, in retrospect, they violate the semantic markup principle described above. I wasn't aware of that at first. For some time I used these, but did notice that editing the documents I was working on involved varying degrees of pain because of these tags. I found that I would move sections around, sometimes taking a top-level section, and making it a sub-section of another. Or, sometimes the reverse: take a subsection, and make it a top-level section.
These section moves were painful because I would have to hunt down the heading tags, and adjust them: when moving an <h3> subsection up a level, I have to remember to change it to an <h2>. This is error prone: sometimes I would miss them in the flat list they appeared in. Or, sometimes I would forget to convert the closing tag.
I recently realized that using the heading tags borders on specifying formatting. Oh, it's not as specific as adjusting a font size with something like the <font> tag (now considered a big no-no). But heading tags are specifying the level of the content. And the level can be determined from the structure of the document -- we shouldn't rely on humans for that. If the level were inferred from the structure of the document, then authors could move content at will without having to worry about indicating (or changing) what level it is at.
The upshot is that heading tags aren't just saying "this is a heading," which would be pure semantic markup. They are saying "this is a heading at level 3," or whatever level, and that implies a difference in formatting.
When I ran into this old problem again, it occurred to me that HTML5 might have finally done something about this. So I did a few quick searches. Here is what I turned up:
- How does Google interpret multiple H1 tags in nested HTML5 sections?
Sounds promising. Seems to imply that the new <section> tag lets all headings be <h1>, solving my problem.
- html5 Doctor: The section element
You're not supposed to use <section> on content that needs to be styled. Isn't that pretty much everything?
- When to Use the HTML5 "section" Element
I'm confused. "... numbered sections of a thesis" sounds like what I want. But we still have "...styling purposes...use the div element instead." This page seems to go back and forth. Finally, "View Source" reveals that this page doesn't use <section>, and has three different levels of heading tags for the "section" headers in the content. Apparently these experts don't believe <section> should be used for that.
The last case cinched it, and I concluded this problem still hasn't been solved.
My requirements are simple: I should be able to markup sections in my document as sections, and indicate what the section heading should be. That markup should be independent of where in the document the section appears.
The simplest thing I could think of looks like this:
<div class="sectiontoc-section"> <span class="sectiontoc-title">Section Title Goes Here</span> <p>Section content goes here...</p> <div class="sectiontoc-section"> <!-- you can nest sections --> <span class="sectiontoc-title">Subsection Title Goes Here</span> <p>Subsection content goes here...</p> </div> </div>
In order to make it work, I would just have to create styles for the classes in the markup.
However, it wouldn't be that simple. I wanted to use this scheme on this site, which is generated by Drupal. I'm using a canned theme I downloaded, and it already has a stylesheet for these. I don't want to have to duplicate all the heading tag styles on sets of nested class selectors. What if they change? What if I want to use this with another theme?
In order to make it work, I had to wrap all of the content with one more <div> so that I could figure out the content depth; my original supposition that these would be directly inside the <body> was wrong within the context of Drupal. That made the final result look like this:
<div id="sectiontoc-body"> <div id="sectiontoc-toc"><!-- placeholder for table of contents --></div> <div class="sectiontoc-section"> <span class="sectiontoc-title">Section Title Goes Here</span> <p>Section content goes here...</p> <div class="sectiontoc-section"> <!-- you can nest sections --> <span class="sectiontoc-title">Subsection Title Goes Here</span> <p>Subsection content goes here...</p> </div> </div> </div> <!-- secctiontoc-body -->
Finally, I cobbled together a Drupal module, installed it in the usual way, enabled it, and voila! If you view source on this page, you can see that I've used the sectiontoc- ids and classes in the markup; the displayed page uses appropriate headings, without the author having to know their depth when authoring. The page has the table of contents at the top, and these are linked to named anchors in the body.