Search code examples
htmlcssaccessibility

How to add alt text to background images? Making background images accessible


I have a site that is displaying many of its images as background images using background-size: cover to size them to completely fill the element while cropping off any parts of the image that don't fit.

The problem is that these images are NOT purely decorative. They are a critical part of the informational content of the page. This means they need alt text in order to be accessible to screen readers and other assistive technologies.

What is the most semantic way to add alt descriptions to background images?

article {
  position: relative;
  width: 320px;
  margin: 5rem auto;
}

figure {
  width: 100%;
  height: 180px;
  /* not accessible */
  background-image: url('http://www.fillmurray.com/300/300');
  background-size: cover;
  background-position: center;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<article class="panel panel-default">
  <header class="panel-heading">
    <h4 class="panel-title">Title of Article</h4>
  </header>
  <div class="panel-body">
    <figure class="article-image"></figure>
  </div>
  <footer class="panel-footer">
    <a class="btn btn-default" href="#">Read</a>
  </footer>
</article>


Solution

  • 2024 Edit

    The object-fit CSS property is now widely supported by browsers, and it's no longer necessary to make an image a background in order to use resizing rules like cover and fill. Because of this, it's now preferential to use a regular <img> element (or <picture>, etc) with an alt attribute. The below approach is no longer necessary.


    Original Answer

    The most semantic way to make a background image accessible is to use both a background image and a regular img tag as well.

    1. Place the img within the element with the background image.
    2. Visually hide the img so that sighted users just see the background image behind it, but users with assistive technologies are still presented the img.

    Note: just setting the image to display: none; will hide also it from assistive technologies, which isn't the goal. A different approach is needed.

    If you're using Bootstrap, it has a handy built-in class for doing just this: .sr-only. If you're not, you can add the styles for that class to your own stylesheet:

    .sr-only {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
      border: 0;
    }
    

    Applying this technique to the example above looks like this:

    article {
      position: relative;
      width: 320px;
      margin: 5rem auto;
    }
    
    figure {
      width: 100%;
      height: 180px;
      /* not accessible */
      background-image: url('http://www.fillmurray.com/300/300');
      background-size: cover;
      background-position: center;
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    
    <article class="panel panel-default">
      <header class="panel-heading">
        <h4 class="panel-title">Title of Article</h4>
      </header>
      <div class="panel-body">
        <figure class="article-image">
          <!-- include the img tag but visually hide it with .sr-only -->
          <img class="sr-only" alt="Bill Murray" src="http://www.fillmurray.com/300/300" />
        </figure>
      </div>
      <footer class="panel-footer">
        <a class="btn btn-default" href="#">Read</a>
      </footer>
    </article>