I’ve been known to rewrite the HTML, CSS, and JavaScript I use for slideshows almost as often as I give presentations. In the past few weeks, I’ve given three talks about HTML5 or related technology, so I used the opportunity to put some thought into how HTML slideshows should be marked up in HTML5.

The spec introduces several new sectioning elements to HTML: <article>, <section>, <header> & <footer>, <nav>, <aside>, and <hgroup>. Unlike some critics, I don’t think these elements are just for putting magazine articles on the web—they’re generally useful in a variety of situations. For slideshows, <article> is a great match for the deck itself, while you can use <section> for each slide. I use the semantic class name deck to distinguish slideshow articles from other kinds of articles.

<article class="deck">
 … slides go here …
</article>

I use <header> and <footer> children of <article> for material repeated at the top and bottom of every slide.

<article class="deck">
 <header>
  <h1>Presentation Title: Presentation subtitle</h1>
 </header>
 … slides go here …
 <footer>
  <address class="vcard">
   <a href="/" class="url fn">Edward O’Connor</a>
  </address>
 </footer>
</article>

Each slide ends up looking like so:

<section>
 <h2>Something</h2>
 <p>Something something</p>
</section>

On the very first (title) slide, I break up the presentation title and subtitle into separate hN elements, but I don’t want the subtitle to affect the document outline. This is precisely the situation the <hgroup> element is intended for.

<section>
 <hgroup>
  <h1>
   <a href="link-to-slides" rel="bookmark">Presentation Title</a>
  </h1>
  <h2>Presentation subtitle</h2>
 </hgroup>
</section>

Navigation

I’d like to be able to advance the slides with SPC or the arrow keys, but also with explicit buttons on-screen. Such buttons allow the user to navigate between the slides, and so this might be a good fit for the new <nav> element.

<nav>
 <ul>
  <li><button id="previous-slide">Previous</button></li>
  <li><button id="next-slide">Next</button></li>
 </ul>
</nav>

// The corresponding JavaScript
$('#previous-slide').click(previous_slide);
$('#next-slide').click(next_slide);
// Listen for keypresses as well
$('html').bind('keydown', handle_keys);

For presentation formats like Ignite or Pecha Kucha Night slides need to be advanced automatically by JavaScript. Instead of Previous and Next buttons, a simple play button will do.

<nav>
 <ul><li><button id="play">Play</button></li></ul>
</nav>

// The corresponding JavaScript
function play() {
 setInterval(next_slide, 15*1000);
 return false;
}
…
$('#play').click(play);

Bookmarking

I’d be nice if each slide were individually bookmarkable. Since the slides are HTML, we can place id="" attributes on each slide, with meaningful IDs that fit each slide’s content. Now each slide will look like this:

<section id="slide-slug">
 <h2>Something</h2>
 <p>Something something</p>
</section>

This implies two things about our JavaScript.

  • At page-load time, we’ll need to jump to the correct slide if there’s a fragment in the URL.

    $(document).ready(function() {
     …
     // If there's a hash, start there instead of the first slide
     if (location.hash != "") {
      set_current_slide(slides.index($(location.hash).get(0)));
     } else {
      set_current_slide(0);
     }
    });
  • At slide-change time, we’ll need to update the fragment in the URL to match.

    function set_current_slide(index) {
     var slide = $(slides.get(index));
    
     // Show this slide and hide the other ones.
     slides.not(slide).hide(); slide.show();
    
     // Update hash if this slide has an @id
     // P.S. JavaScript could use an anaphoric `if'.
     var id = slide.attr('id');
     if (id) {
      location.hash = id;
     }
    }

What about older browsers?

Older browsers differ wildly in their handling of unkown elements, so you may need to employ several workarounds to use these new elements.

For IE, the most excellent html5shiv makes the browser recognize new elements. It’ super easy to use: just drop one <script> into place with a conditional comment, and you’re good.

IIRC, some older Firefoxen will treat unrecognized elements as inline unless you style them as display: block in a <style> element directly in the HTML, like so:

<!-- Make older browsers handle new elements. -->
<style>
 article, footer, header, hgroup, nav, section {
  display: block;
 }
</style>

If you’d like to see how it all adds up, take a look at any of the three decks I linked to above, or take a peek at presentation.css and presentation.js.

Comments

  1. in august of 2009, you wrote, “take a look at any of the three decks I linked to above,”

    …but you didn’t (link, that is).

    cheers,

    — cz

    Chris, 29 April 2010

  2. What should we do about graphics? The more I use PowerPoint, the more I move away from bullets and text to simple drawings; how would you handle those in an HTML5-based slideshow package? Punting (i.e., saying "It's up to the creator to draw something in SVG and then link to it") isn't satisfying... :-(

    Greg Wilson, 27 September 2010

Add a comment

Posting...