dimsemenov / PhotoSwipe

JavaScript image gallery for mobile and desktop, modular, framework independent
http://photoswipe.com
MIT License
23.96k stars 3.32k forks source link

Accessibility: links need role="button" #1717

Open ianthedev opened 3 years ago

ianthedev commented 3 years ago

After initializing the plugin, links are still look like links to assistive technologies. Assistive technologies do not know these links will trigger a dialog.

So the links need role="button" and tabindex="0" and the href attributes would need to be removed.

lnfel commented 3 months ago

Just encountered the same issue today, since the container element is an acnhor tag it messes up the announcements by assistive technology. I played around a bit and found out that we can use other element as the children of gallery:

<ul class="project-grid">
  {#each projects as project}
    <li on:keydown={triggerPSWP} tabindex="0" aria-label="{project.title} Project: {project.description}" class="project-card">
      <!--
        Hiding the actual pswp anchor element as the first child of our
        registered pswp children element (project-card). Hidden for both screen reader and visual users
      -->
      <a href={project.imageURL} target="_blank" rel="noreferrer" data-pswp-width="2500" data-pswp-height="1200" aria-hidden="true" class="pswp-link hidden">{ project.title }</a>
      <!--  Other content here -->
    </li>
  {/each}
</ul>

Our pswp gallery is the element with a class of project-grid and the children are li elements with a class of project-card. By default PSWP tries to look inside of the children for the very first anchor element, this is why it is important we ad the hidden anchor link as the very first child of the registered pswp children element.

Now if we click on the li element, it will trigger PSWP and reveal the image and animate it on screen. But one issue here is that PSWP will only listen for click events and not keyboard events on the registered element and only anchor element can do navigation when pressing Enter or Space key which PSWP listens to. This is where we add tabindex and attach our custom keydown listener on li element as denoted by the markup on:keydown={triggerPSWP}, below is the code to trigger a click event on the hidden anchor link:

function triggerPSWP(event) {
  if (event.key === 'Enter' || event.key === ' ') {
    event.preventDefault()
    const pswpTrigger = event.target
    if (pswpTrigger instanceof HTMLElement) {
      const pswpLink = pswpTrigger.querySelector('.pswp-link')
      if (pswpLink instanceof HTMLAnchorElement) {
        pswpLink.click()
      }
    }
  }
}

With this PSWP is now accessible friendly! 🎉