Chris Bateman

Accessible CSS Transitions

Here’s a simple example: we want to animate a container open and closed, perhaps as part of an expand/collapse treatment.

.acc-demo-1 {
  height:40px;
  padding:10px;
  overflow:hidden;
  transition:0.5s all;
}
.acc-demo-1.hidden {
  height:0px;
  padding:0px 10px;
}
Toggle
Lorem ipsum dolor sit amet.

Good enough, you say? Back the train up: most screen readers are still going to read the content of that div when it’s hidden. Setting the height to zero isn’t enough (except in VoiceOver, I think – this could definitely change in the future, though). So how about we just add ‘display:none’ when it’s hidden?

.acc-demo-2 {
  height:40px;
  padding:10px;
  overflow:hidden;
  transition:0.5s all;
}
.acc-demo-2.hidden {
  height:0px;
  padding:0px 10px;
  display:none;
}
Toggle
Lorem ipsum dolor sit amet.

This kills our transition effect in both directions, since the div is getting yanked in and out of the render tree. Fortunately, the visibility property is animatable, so that will work, but with a caveat: if we immediately transition the visibility when we’re hiding the div, it’ll disappear before we have a chance to see it animate closed. So we need to add a second transition declaration to change the visibility after the animation is done.

.acc-demo-3 {
  height:40px;
  padding:10px;
  overflow:hidden;
  transition:0.4s height, 0.4s padding;
}
.acc-demo-3.hidden {
  height:0px;
  padding:0px 10px;
  visibility:hidden;
  transition:0.7s height, 0.7s padding, 0s visibility 0.7s;
}
Toggle
Lorem ipsum dolor sit amet.

That’s more like it. And as you can see, you can also use this technique to make your transition do different things going in different directions – like changing the speed.

And yeah, I know I didn’t add the other accessibility stuff that should be there for expand/collapse.

Tell me what you think: @batemanchris