Creating an Accessible Media Library Photo Gallery

Category
Drupal Version

Media Library in recent versions of Drupal 8 and Drupal 9 offers a lot of great functionality for managing and reusing images (and other media types), but out-of-the-box it has a notable accessibility issue.

If you try to configure an image media type so that the user can select the thumbnail image and get the full-size version, the option for this (setting "Link image to" to "File") gives you only a link around the image, with no way to include the media item's built-in Name field.  Worse, the link will be presented to screen readers with the image's alternate text, which may not be appropriate for link text, and training content managers on how to handle this special usage of the alternate text field would be an uphill battle.

Correcting this problem requires both changing your media type configuration and adding a custom template:

Media Type Configuration

  1. Edit your Media type and switch to the Manage display tab
  2. Move the Thumbnail and Name fields up above the "Disabled" separator, but leave Image enabled as well.
  3. Configure the Thumbnail settings as desired, then configure Image with the "URL to image" format pointing to the "original image".
  4. Save your changes.

Custom Template Configuration

First, create a template file named "media--XXXXX--default.html.twig" where "XXXXX" is the machine name of your Media Type.  Place the following inside it:

{%
  set classes = [
    'media-library-item',
    'media-library-item--grid',
  ]
%}

<div{{ attributes.addClass(classes) }}>
  <a href="{{ content.field_media_image.0['#markup'] }}">
    {{ content.thumbnail }}
    <span class='visually-hidden'>Full Size Version of Image "</span> {{ content.name }} <span class='visually-hidden'>"</span>
  </a>
</div>

If you put your template into a sub-theme, then just flush your caches and it should take effect.  If you put your template into a module, then add the following to your .module file:

function YYYYY_theme($existing, $type, $theme, $path) {
  return [
    'media__XXXXX__default' => [
      'base hook' => 'media',
    ],
  ];
}

Replace "XXXXX" with the machine name of your media type, and replace "YYYYY" with the machine name of your module.  Flush your caches, and the template should take effect.