Phone number links and accessibility

One design challenge that used to stump me was making phone numbers accessible in the browser while still being functional. The WCAG 2.0 guidelines state:

Link underlines or some other non-color visual distinction are required (when the links are discernible to those with color vision).

Let’s consider for a moment how we’d normally code a phone number link to function when tapped in a mobile browser:

<a href="tel:123-456-7890">123-456-7890</a>

In the past, if we didn’t think it made sense to show a phone number link on a non-mobile screen, we’d style it to look like plain text, and then display it as a link for mobile screens. But that solution goes against the above guideline. Additionally, screen readers will read the phone number as a link even if it’s not styled like one.

Another thing to avoid is creating two separate elements for the phone number and using conditional CSS to display the appropriate one for mobile or desktop. If CSS is disabled in the browser, both phone numbers will be displayed (yes, people do disable CSS).

“Okay, dude, I get the problem. What can be done?”

Swap out the element

We can replace elements in the DOM with JavaScript. In this scenario, if we created a <span> for a phone number, we could replace it in the DOM with an <a> for smaller screens.

So, given:

<span id="num">123-456-7890</span>

We can add a little jQuery to the mix and use the replaceWith() method:

$("#num").replaceWith(function () {
  return $("<a href='tel:" + $(this).html() + "'>" + $(this).html() + "</a>");

(You can do the same thing with plain JavaScript using the replaceChild() method.)

Now we need a condition to determine when to replace the element. Since we’re making this change based on screen size, a screen width of 700px as the trigger might give us the greatest flexibility across devices. (It’s not perfect, but no one ever said building the web was easy.)

if ($(window).width() <= 700) {
  $("#num").replaceWith(function () {
    return $("<a href='tel:" + $(this).html() + "'>" + $(this).html() + "</a>");

Note: much of the feedback I've received points out that this could reduce overall accessibility when interacting with VoIP technology. So, YMMV.

Here’s a demo showing this technique when the phone number’s container is a specific size.

Now we have a solution that is both accessible and functional when appropriate. To me this makes sense, although I’ve heard concerns with this disrupting VoIP features with non-mobile screens. If you’d like to improve upon this method or have another solution for this scenario, I’d love to see what you come up with. Happy coding!