Preventing Overflow With sr-only

The sr-only class is a common convention for visually hiding an element while keeping it visible to screen readers. If not implemented properly though, it can cause some unexpected overflow due to absolute positioning.

To review, the sr-only class (visually-hidden is another common name) looks something like this:

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

Using this, let’s imagine a scroll container with some cards inside. We want the container height to cap at 300px, where the cards inside will scroll. The cards themselves are quite simple, and we’re using our sr-only class to display some hidden text.

<html>
  <head>
    <style>
      .container {
        height: 300px;
        overflow: scroll;
      }

      .card {
        height: 200px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="card">
        <p class="sr-only">Hidden text</p>
        <p>Visible text</p>
      </div>

      <div class="card">
        <p class="sr-only">Hidden text</p>
        <p>Visible text</p>
      </div>

      ...
    </div>
  </body>
</html>

If you run this in the browser, you’ll notice an interesting issue. The body of the document begins to scroll! This doesn’t make sense at first since the cards themselves scroll, but the issue is that our sr-only class is using position: absolute which means without a position: relative parent in the scroll container, the elements will be positioned absolute relative to an item outside (the body in our case), and thus their space will be calculated outside the scroll container, forcing it to scroll.

The simple solution here is to add relative to our card class, though the fix for you may be slightly different depending on your use case.

.card {
  height: 200px;
  position: relative;
}