How to make picture element accessible for each breakpoint?

737 views Asked by At

Let's say you have a picture element similar to this:

<picture class='my-image'>
   <source media="(min-width: 1024px)" srcset="large.jpg">
   <source media="(min-width: 768px)" srcset="med.jpg">
   <source srcset="small.jpg">
   <img src="small.jpg" alt="">
   <p>Accessible text</p>
</picture>

But let's say that the context of the image is different for each breakpoint. Perhaps at large size, the picture is of a man standing in front of a tree. But at mobile size, it's just a picture of a tree.

Sometimes, certain pictures work well at mobile sizes and other pictures don't depending on page layouts, etc.

Anyways, with the picture element you can only specify the alt= attribute in a single place for the entire picture element. But if the image context changes between each breakpoint, is it possible somehow to specify different alt= attributes? Do you have to use JavaScript for this (which may or may not be screen reader friendly)?

2

There are 2 answers

2
Adam On

Perhaps at large size, the picture is of a man standing in front of a tree. But at mobile size, it's just a picture of a tree.

It looks to me that this kind of situation appears only when using a strictly "decorative image".

If those images are stictly decorative and you can't put them for certain reasons in CSS, then the alternative text has to be empty.

If they are not decorative images, then the easiest solution is to use two different picture tags which does not require any Javascript.

3
guest271314 On

Substitute srcset for src at <source> element, use onerror event of <img> element and window.matchMedia() to set alt attribute.

  <script>
    function handleError() {
      var sources = document.querySelectorAll("picture source");
      var img = document.querySelector("picture img");
      for (var i = 0; i < sources.length; i++) {
        if (window.matchMedia(sources[i].media).matches) {
          img.setAttribute("alt", sources[i].dataset.alt);
          break;
        }
      }
    }
  </script>
  <picture class='my-image'>
    <source media="(min-width: 1024px)" srcset="large.jpg" data-alt="large">
    <source media="(min-width: 768px)" srcset="med.jpg" data-alt="small">
    <source srcset="small.jpg" data-alt="small">
    <img src="small.jpg" alt="" onerror="handleError()">
    <p>Accessible text</p>
  </picture>

plnkr http://plnkr.co/edit/GwwHWujq1Nt8V33zmJLS?p=preview