Do we need a new heading element? We don’t know.

Great insightful post by Jake Archibald on the generic <h> element, which could act as a replacement for the current set of <h1>, <h2>, <h3>, …

I always thought this to be a good case, as it’d would allow you to move components around in the DOM, and the “importance”
of the heading would be defined based upon its position/nesting level (e.g. the outline algorithm).

The suggestion is that <h> would solve this, as browsers would implement it & do the right thing in terms of the accessibility tree.

This is a common mistake in standards discussion – a mistake I’ve made many times before. You cannot compare the current state of things, beholden to reality, with a utopian implementation of some currently non-existent thing.

If you’re proposing something almost identical to something that failed, you better know why your proposal will succeed where the other didn’t.

We need evidence. And the first step is understanding what went wrong with the previous proposal.

Do we need a new heading element? We don’t know →

Fixing HTML Video on Mobile


Samir Zahran on how and why they built Whitewater, an open source video encoder and player for their site:

Common HTML5 Video features such as preloading and autoplay are completely missing in some browsers. The scripting APIs are limited compared to what’s available on desktop. Worst of all, Safari on the iPhone (the most popular mobile browser to visit our site) does not allow inline video playback at all (not until iOS 10 is released)

It renders on <canvas> and requires you to first encode your video to the Whitewater format which uses diffmaps.

Fixing HTML Video on Mobile →
Whitewater Mobile Video →

Note: In case you don’t want to encode your videos you can – alternatively – use the hack that powers “players” such as iphone-inline-video: manually change the currentTime of the video element.

Here’s a little snippet of a (non-public) project that I’m working on that might be of help:

play(reset = false) {

  // Reset to start if need be
  if (reset) { = 0;

  // Store time
  this.lastTime =;

  // "Play" the video, using requestAnimationFrame


pause() {
  this.rAF && cancelAnimationFrame(this.rAF);

_rAFRender() {

  // Calculate time difference between this and the previous call to _rAFRender
  const time =;
  const elapsed = (time - this.lastTime) / 1000;

  // More time has passed than the framerate
  if (elapsed >= (1 / 25)) {

    // Seek the video to currentTime, thus rendering a new frame even though it's not playing = + elapsed;

    // Store time as lastTime
    this.lastTime = time;


  // We are not at the end of the video: keep on rendering
  if ( < {
    this.rAF = requestAnimationFrame(this._rAFRender);


If you create an <audio> element in parallel, you can even sync up the audio from the video with it – a feature Whitewater has not.

Note to self: I urgently need to release this component …

Using the Browser Developer Tools to their full potential

Are you using the developer tools to their full potential? The biggest positive about the developer tools is that they are incredibly easy to use, but as a result developers often miss out on a large proportion of the functionality provided. Inspired by a video talk by Paul Irish and Pavel Feldman, I’ve compiled a list of “secrets” of the developer console.

25 Secrets of the Browser Developer Tools →