Semantic Animation

Avatar of Chris Coyier
Chris Coyier on (Updated on )

I recently said this when asked about new tools (e.g. Edge) for building CSS animations:

Empty divs used for nothing but styling were non-semantic and a bad idea before CSS animations and they are a bad idea now.

I stand by that. I feel like we’ve come a long way as an industry getting everyone on board with semantic markup. Do this, and reap the great rewards of speed, accessibility, maintainability, and SEO.

Then a new shiny thing comes along and the first thing we do is start abandoning our own rules. “Oooo I can make a bird fly across the screen‽” Order me up a few more of them empty divs! I’m surely guilty of this. It doesn’t feel like that big of a deal when you’re doing it, especially in moderation.

But CSS animations are here to stay. General best practices are going to emerge regarding what types of things we should be using them for, how much is too much, how to approach them semantically, how to offer fallback content, etc. I thought I’d throw in one little idea I had.

Let’s consider what animations do for a design. They can give it mood. They can give it attitude. Like other aspects of design, they affect how a user might feel about that page. But they only do these things for sighted users. The empty div does none of these things for non-sighted users. It’s just useless cruft.

<div class="moon">
  <!-- I offer nothing to non-sighted users -->
</div>

What if we were to take that empty div and try to accomplish for non-sighted users all the same things we are accomplishing for our sighted users. Simply putting descriptive text into those divs might be able to get it done for us. Similar to an alt tag for images, but actual inline content meant to be read/enjoyed in same way the animation is meant to be seen/enjoyed.

Perhaps our animation is of a moon rising, and as it rises the sky and ground turn to black. We need two elements to accomplish our animation, and so perhaps they contain the lyrics to CCR’s Bad Moon Rising

<div class="moon">
   I see a bad moon rising
   I see trouble on the way
</div>

<div class="ground">
   I see earthquakes and lightnin’
   I see bad times today
</div>

The CSS hides this text from view and calls the keyframe animation:

.ground, .moon {
   text-indent: -9999px;
   overflow: hidden; /* text-indent without this can cause choppy animation */
}

.ground {
   -webkit-animation: ground-to-black 5s ease;
   -moz-animation:    ground-to-black 5s ease;
   -o-animation:      ground-to-black 5s ease;
   animation:         ground-to-black 5s ease;
}

.moon {
   -webkit-animation: rising-moon 5s ease;
   -moz-animation:    rising-moon 5s ease;
   -o-animation:      rising-moon 5s ease;
   animation:         rising-moon 5s ease;
}

/* Plus various keyframe declarations */

View Demo

Notice the names of those keyframe animations. That’s another discussion to have in the “semantic animations” vein. Another time.

This text could be anything that relates to the animation. It could describe the animation literally. It could be a poem that elicits the same emotion as the animation. It could be an <audio> element.

Woah there, fancy designer boy.

I don’t use screen readers, so I don’t get to make the call if this is a good idea or not. I imagine there is already enough cruft to fight through that this, despite the good intentions, might be just another thing obstacle on the way to “real content”.

I suppose it’s like everything else in this world: it depends.