Progressive Enhancement Techniques 1: the HTML

Contributing Editor

web layersIn my earlier articles, we discussed progressive enhancement and why it’s generally a better choice than graceful degradation. This is the first of a three-part series that illustrates how to build a simple tabbed box using progressive enhancement techniques.

Web Page Layers

Web pages are built in three layers:

  1. HTML defines the document content and structure
  2. CSS defines the layout and styling — it enhances the HTML
  3. JavaScript defines page functionality such as client-side form validation, animations and effects — it can enhance both the HTML and CSS

HTML is the only layer you can rely on with any certainty. Most browsers will display something — even if you are providing XHTML 1.1 content to a device that only supports HTML 3.2.

The majority of browsers offer CSS but the level of support varies. Users can disable CSS or specify their own stylesheets in preference to yours. Some browsers such as screen readers or Lynx could completely ignore your CSS.

Finally, JavaScript is the least reliable technology layer. Most browsers support JavaScript but interpreter engines differ and many people disable the language for security reasons. The likelihood of a user having JavaScript will vary from site to site but, in general, up to 5% of visitors will not have scripting enabled.

POSH Content

POSH is an acronym for “Plain Old Semantic HTML”. The term was coined by the microformats community, but it’s a useful concept for all developers who strive to build well-structured, accessible, semantic and valid HTML:

  • use semantic elements and attributes, e.g. h1 for your main title, p for paragraphs, table for tables of data (not presentation), etc.
  • use semantic id and class names when necessary
  • use the simplest and least amount of HTML possible
  • validate your code.

In the following example, we will build a tab box. The code is a simple client-side only widget, but the same concepts can be adapted throughout your development. Almost any control you can imagine will have a POSH equivalent.

Building the Tab Box HTML

At it’s most basic level, a tabbed box is a list of in-page links to associated content. The HTML structure could therefore be defined as follows:


<!-- tabs (links) -->
<ul class="tabs">
	<li><a href="#tab1">Tab 1</a></li>
	<li><a href="#tab2">Tab 2</a></li>
	<li><a href="#tab3">Tab 3</a></li>
</ul>

<!-- tab content -->
<div class="tabcontent">

	<div id="tab1">
		<h2>Tab 1 Content</h2>
		<p>This example uses progressive enhancement techniques to create a tabbed content box.</p>
	</div>
	
	<div id="tab2">
		<h2>Tab 2 Content</h2>
		<p>The control will work without CSS and JavaScript if necessary. Even a text-only browser such as Lynx will work.</p>
	</div>

	<div id="tab3">
		<h2>Tab 3 Content</h2>
		<p>For the best experience, users should use IE6+, Firefox 2+, Opera 9+, Safari 3+ or Chrome 1+ and have JavaScript enabled.</p>
	</div>

</div>

This page should work in almost any web browser with support for HTML 4.01 or XHTML 1.0. Older browsers will continue to display the content even if the links do not work as expected.

HTML only screenshot

Note:
Semantic HTML purists will point out that the code doesn’t follow POSH guidelines because it suffers from a DIV-itis. I agree — none of the DIVs are required for the content. They have been added because it will allow us to create a better CSS-only solution and simplify our JavaScript code.

In a perfect world, your HTML would be simple and unconcerned about layout or functionality. Unfortunately, web development is not perfect and it’s often necessary to make compromises. Adding an extra tag or two for CSS or JavaScript hooks won’t destabilize the web; just don’t do it unnecessarily.

In my next post, we add a the CSS layer to make it prettier and improve the usability without adversely affecting the functionality.

Resource links:

Other parts in this series:

Related reading:

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • the.peregrine

    Progressive enhancement seems a mystery to so many people, and it’s hard for me to understand why as they plunge into the intricacies of javascript coding before getting the real meat of HTML. Thanks, Craig, for boiling this down so nicely!

  • http://www.optimalworks.net/ Craig Buckler

    Thanks the.peregrine.

    I think the problem is that novice developers are swayed by fancy effects and Ajax techniques. Many JavaScript libraries make these easy to achieve but, unless you understand what’s going on below the surface, you can end up with inaccessible pages which are limited to a subset of modern browsers.

    Unfortunately, it’s tempting to tinker with the wallpaper and furnishings when we should concentrate on building the house with solid foundations!

  • http://www.baymard.com jamieappleseed

    @Craig Buckler,

    I think that’s true. HTML (and data structure) is the least sexy part of an already very unsexy topic, which means a lot of people will ignore it at high costs.

    Finally, no matter how much we hate it, I think a lot of people also just don’t care about semantic code that validates or clean HTML, and considers it a waste of time if they with less (upfront) effort can get something that works, today.

  • Michał Czernow

    Some browsers such as screen readers or Lynx will completely ignore your CSS.

    That’s not entirely true. I had experience with screen readers that ignore any element with display:none or visibility:hidden declared. That’s why I stoped using these declarations for eg. css drop down menu.

  • http://www.boodelprod.com doug-o

    I am sure I am nuts but I love creating semantic HTML. Each page has it’s own unique challenges and I find it fun to apply as much semantic meaning as possible. It’s like doing a crossword: a challenge and relaxing.

  • http://www.optimalworks.net/ Craig Buckler

    @Michal Czernow
    Whoops – “will completely ignore” should have been “could completely ignore”. It’s been fixed, thanks.