Video Subtitles in CSS: accessible, standard, self-contained
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

This proof-of-concept use the in-HTML MetaFragments convention I drafted during the MozNewsLab 2011 to display synchronized subtitles using only CSS3 animations and attribute selectors.

No javascript, external subtitle file or proprietary format is used for the subtitles:

the subtitles are fully contained in the HTML page as standard links pointing to their corresponding part of the video, using standard media fragments URI.

As there is currently no way in pure CSS3 to style time-based elements in relation to their own timeline, if you stop the video manually by using the contextual menu, subtitles will get out of sync. You always have the possibility to reset the sync by starting the video again via a simple link.

The CSS use prefixed selectors, but you can take a look at how much more clean and simple it is with only the official syntax here: unprefixed style sheet.


These subtitles are totally accessible and retro-compatible. They work even if you can't access or play the video, and they are totally useful if CSS is turned off because they are standard, clickable, readable links.

Timecode is self-contained as both totally standard media fragments URI (direct click-throught not supported on Firefox) and a custom HTML5 data attribute.

Given a properly timed transcript, it's very easy to generate this sort of subtitles. I did it manually using a (powerful) text editor. A script would make thing even easier.


We would need to add a little bit of javascript to keep the subtitles in sync if people stop the video.

What if we had a :time pseudo-class for media elements?

No potential addition of Javascript code would be necessary at all if there was a CSS pseudo-class corresponding to the time in the VIDEO element, used in conjonction with the content property

Below is an example CSS code to illustrate how we could use a :time (ie. position in the media) pseudo-class on VIDEO and AUDIO elements – this is fictionnal code, as the time pseudo-class doesn't exist at the moment.

This code match the A element with the custom data attribute data-time="0:00:24.200,0:00:24.880" and that is the sibling of a VIDEO element playing at 24200ms.

video:24200~a[data-time="0:00:24.200,0:00:24.880"] {
  animation-name    : appear;
  animation-duration: 680ms;
  animation-delay   : 24200ms;

Another way to use a :time pseudo class would be to append some content to the VIDEO element at some point in time

video:24200::after {
  content: "I love this part of the video !";

What would you do with a :time pseudo class? Does it makes sense to you? Or are you finding that idea totally absurd? :-)

You can find me on twitter here: