Growing with the Web

Making abbr elements touch accessible

Published
Tags:

Ever used an abbr element in your HTML only to have it rendered completely unusable when viewing the page on a mobile browser? Me too, so I made a library to fix it.

Example of abbr-touch.js in action

abbr-touch.js is a tiny JavaScript library that attaches touch events to abbr tags, which enable the display of the expanded term to the user. The library is very flexible only doing the bare minimum required to get the message to the user. By default it displays the message using an alert, but a custom handler can be used to display the expanded term in what ever way you desire.

The ‘touch’ event is done with touchtap-event.js which only fires the event when the screen is actually touched, not clicked. So the library should not impact users with a mouse.

This is a simple example of initialisation.

abbrTouch(document.querySelector('article'), function (target, title, touchX, touchY) {
  // display the element
  alert(title);
});

My blog uses the library with a more complex handler that slides up the meaning of the term from the bottom of the screen and displays it for a period based on the length of the message. Here is the initialisation JS which fills the element’s content and updates its visibility to the correct state.

(function (abbrTouch) {
  'use strict';

  var tooltipTimeout;

  abbrTouch(document.querySelector('article'), function (target, title, touchX, touchY) {
    var tooltip = getTooltipElement();
    // Ensure the tooltip is ready so that the initial transition works
    setTimeout(function () {
      updateTooltip(tooltip, target.innerHTML, title);
    }, 0);
  });

  function getTooltipElement() {
    var tooltip = document.querySelector('#abbr-tooltip');
    if (!tooltip) {
      tooltip = document.createElement('div');
      tooltip.id = 'abbr-tooltip';
      // Technically this is duplicate content, just exposing it on mobile
      tooltip.setAttribute('aria-hidden', 'true');
      document.body.appendChild(tooltip);
    }
    return tooltip;
  }

  function updateTooltip(tooltip, term, expandedTerm) {
    var text = term + ': ' + expandedTerm;
    tooltip.innerHTML = text;
    tooltip.classList.add('visible');

    if (tooltipTimeout) {
      clearTimeout(tooltipTimeout);
    }

    var timeoutLength = text.length * 120;
    tooltipTimeout = setTimeout(function () {
      tooltip.classList.remove('visible');
    }, timeoutLength);
  }
})(abbrTouch);

The following CSS is then used to style the tooltip element.

#abbr-tooltip {
  position: fixed;
  bottom: -5em;
  left: 0;
  right: 0;
  background-color: #FFF;
  border-top: 1px solid #000;
  text-align: center;
  font-size: 1.4em;
  padding: 1em .5em;
  transition: bottom cubic-bezier(.73,0,.27,1) .3s;

  // Layer hack to force the tooltip on to another layer
  -webkit-transform: translateZ(0);
  transform: translateZ(0);

  &.visible {
    bottom: 0em;
  }
}

You can try out the library by touching one of these terms acronyms on this post using a touch-enabled device or touch emulation on a desktop browser. The library is up on GitHub with a live demo here.

Like this article?
Subscribe for more!