Use the links below to share The <h> Hierarchy: Using Heading Tags the Right Way on your favorite social networks.

Back to the Article >>

The <h> Hierarchy: Using Heading Tags the Right Way

September 17th, 2008 in Design Tips & Tutorials

by: Matthew Griffin

If you've been using CSS and web standards for awhile, then you probably already know that the HTML heading tags h1-h6 are meant to denote a hierarchy of importance—the most important, of course, being <h1> and the least important being <h6>. If you're new to CSS layouts and web standards then you might think heading tags just make text bigger or smaller. But there's a lot more to heading tags than most web designers realize. And in order to build beautifully semantic websites that degrade gracefully, a proper understanding of the <h> tags is a must.

Getting the Hierarchy Right

As I mentioned above, heading tags place more or less importance on a block of content depending on the number of the heading. The W3C says:

A heading element briefly describes the topic of the section it introduces. Heading information may be used by user agents, for example, to construct a table of contents for a document automatically.

It's important to progress sequentially through the hierarchy of headings but it's not necessary to have all six on every page. For example, one page might have a main title(<h1>) and then a subtitle (<h2>) and that's it. This is perfectly acceptable. However, if the page were to jump from <h1> straight to <h3>, that would technically be incorrect. Although the page would still render perfectly fine in a browser, converting the document to other presentations could cause problems. It's best to just do it right the first time.

Also, you should only have one <h1> tag per page. The <h1> tag is meant for the most important heading on the page. Having more than one most important heading wouldn't make any sense. However, once the most important heading (usually the page title) has been established, you may use as many h2-h6 tags as you find appropriate.

Using <h> Tags in the Layout

When we think about heading tags, the first thing that comes to mind (especially for those of us who cut our teeth on Front Page) is body copy. The <h1> tag would be at the top of the body copy and the rest of the <h> tags would follow in the text below.  But a  well-structured web page uses <h> tags where they are semantically appropriate—where they most effectively describe the content they contain. For this reason, many times, layout elements should be <h> tags rather than generic <div> tags. Remember, <h> tags are block-level elements by default just like <div> tags, which means they can do everything a <div> tag can do.

A lot of designers (myself included) have been guilty of thinking that CSS layout is the same as semantic layout. This just isn't the case. Let's take a look at some sample code that uses well-structured XHTML but is semantically meaningless:

<div id="header">
    <div class="logo"><img src="logo.gif" alt="Mirificam Press" /></div>
    <div class="tagline"><img src="tagline.gif" alt="Information for Web Designers" /></div>
</div>

Structurally, there is nothing wrong with this markup. Add a little CSS and it will look great in just about any browser. The problem is that the generic <div> has no meaning—it doesn't describe the content it holds. So, for example, a mobile device with limited CSS support,  or a screen reader would have no idea that your logo is the most important title on your page. The page doesn't degrade gracefully at all—it degrades to a big pile of mushy text. This is how it should have been marked up:

<div id="header">
    <h1>Mirificam Press</h1>
    <h2>Information for Web Designers</h2>
</div>

Not only is this markup semantically correct, it's more concise and readable than our original example. Now, to turn our <h1> and <h2> tags into images for CSS supporting browsers, we just add a little CSS that might look something like this:

#header h1 {
    background: url(logo.gif) no-repeat;
    text-indent: -9999px; /* This gets the text out of the way */
}
#header h2 {
    background: url(tagline.gif) no-repeat;
    text-indent: -9999px; /* This gets the text out of the way */
}

You would also have to add height and width attributes to the <h1> and <h2>  to correspond with the dimensions of the logo.gif and tagline.gif images, but other than that, you're ready to go. The content is completely separated from the style/presentation which is exactly how it should be. You probably also noticed that the text-indent is set to -9999px on the <h1> and <h2> tag. This is a trick I learned from Designing with Web Standards by Jeffrey Zeldman. It pushes the text out of the visible area in browsers that support CSS. Everything that doesn't support CSS sees the text.

  • 15 Comments
  • 4892 Views

Back to the Article >>