The rectangle behind you

Checklist for writing an HTML slide engine

Marcin Wichary
The rectangle behind you
5 min readDec 23, 2014

--

I usually write all my presentation decks in HTML, starting from an empty file. Why? A few years ago, Smashing Magazine interviewed me and what I said then still rings true:

I actually make a point of starting things from scratch, even if they have been written elsewhere, or even by me before, because it allows me — you know, in a fast-moving environment where HTML5 and CSS3 change a lot — it allows me to learn all of those new things, to try a different approach, to think about how I did it the last time and try to do it differently, just for the sake of doing it differently. And that always feels really great. That approach probably only works for, like, little projects, little goofy experiments that I do. I don’t know… you can’t really rewrite Gmail every single month from scratch. [Laughter] But it’s kind of been working for me.

These are some of the things I think about every time I start from scratch:

Handling failures

Some of my slides are not very reliable; they are usually not much more than prototype-quality code.

This means that things can go wrong. So I build my slide decks in a way where I can simply press ⌘+R, and the current slide reloads again. If that happens, no one will even notice. This is usually as simple as putting the current slide number in the URL, and then reading it back on page load.

The number of the current slide (3) is visible in the URL.

If my presentation has a chance of crashing the browser (yes, that happened to me a few times), I put the current slide in localStorage, and read back on browser restart. It’s possible to get this for free, actually, depending on how the browser I use handles restarts… just need to test it once or twice.

Likewise, if my slide deck is in any way stateful — if there are things I change on one slide that affect future slides — I similarly put them in localStorage on change, and then read off of it when (re)loading the presentation.

If my presentation connects to other devices (for example, I sometimes use a remote that’s a website accessed through my iPhone, talking to the main presentation via Node), I build in some systems to try to quietly reconnect in case of failure. Quietly, since dumping error messages on the main screen means your entire audience will see it.

No internet access

Your presentation should work without internet access, since internet connectivity at conferences is often unreliable.

This means:

  • using local fonts instead of services like Typekit
  • making local copies of any outside resources (e.g. images)
  • preparing backups for when I need to refer to outside websites I can’t control (take screenshots or screencasts)

The easiest way to check whether your presentation works offline is to shut down wi-fi, load the presentation, and look into web inspector to see if there are any missing resources:

In this case, the slide deck relies on two internet services: Google Web Fonts for fonts, and Click That ’Hood game. We should save the fonts locally, and then make a copy of the game running locally (or replace it with a video).

The mouse pointer

You don’t want the mouse pointer to be hanging there on the slide, where you left it, like the gross house fly. Unfortunately, it’s not possible in HTML to simply hide or show the mouse pointer at a moment’s notice, which would be perfect — you could just fade it out after some delay, and fade it back in if you start moving it.

But, there are other options.

First, if you don’t need your mouse pointer for anything, you can simply hide it wholesale for your entire slide deck.

body {
cursor: none;
}

If you do, however — for example for some of your interactive slides — a solution I use is to designate a little invisible rectangle (usually 100×100 pixels) in a bottom right corner of the slide, above everything, where I could “park” my mouse pointer, and it disappears there.

The bonus side effect of doing that is that I could click on this hidden rectangle to reclaim focus if the presentation has input fields, iframes, etc. (The focus is important for the main keyboard shortcuts to start working.)

Demonstrating the hidden rectangle “swallowing” the mouse pointer in the lower-right corner

Rewinding slides

It shouldn’t really be necessary to ever go back a slide in your talk, but for the rare instance it might, I make sure that no animations are played as I go back.

Likewise, if you go forward the second time, no animations should play again.

For debugging and working on the talk, I usually write a little piece of code that ensures, as long as I hold Shift, moving between slides never fires animations — even the first time around.

function nextSlide(instant) {

}
function onKeyDown(event) {
switch (event.keyCode) {
case 39: // Right arrow
case 40: // Down arrow
if (document.activeElement == document.body) {
nextSlide(event.shiftKey)
event.preventDefault()
}
break
}
}

Keyboard shortcut collisions

Let’s say you have an input field in the middle of the slide. Let’s also say you use space or right arrow to advance to the next slide.

You probably want to make sure that pressing space or right arrow in that input field doesn’t also happen to advance your slide.

Seems simple, but JavaScript might not be on your side here. Trust me. I’ve been there too many times.

function onKeyDown(event) {
switch (event.keyCode) {
case 39: // Right arrow
case 40: // Down arrow
if (document.activeElement == document.body) {
nextSlide(event.shiftKey)
event.preventDefault()
}
break
}
}

Iframe preloading

If your deck has a lot of iframes embedding other sites (or even your own pages), it might be good to not load them straight away, but preload them if you get close to their respective slides… and unload the moment you pass them.

<iframe data-orig-src=’inside/glyph-tester/’></iframe>function onSlideEnter(slideEl) {
var iframeEl = slideEl.querySelector(‘iframe’)
if (iframeEl && !iframeEl.classList.contains(‘loaded’)) {
iframeEl.src = iframeEl.getAttribute(‘data-orig-src’)
iframeEl.classList.add(‘loaded’)
}
}

The rectangle behind you, a series of articles about interactive presentations.

By Marcin Wichary (@mwichary)

--

--