How does the sr-only actually work?

Hi everyone !

I am actually going through the FCC Curriculum (really cool job btw !), and just finished the “Applied Accessibility: Make Elements Only Visible to a Screen Reader by Using Custom CSS” lesson.

I do actually wonder how the screen reader’s sr-only property is working: how does it know what it should replace? And how does it know which size or where it should place the table instead of the figure ? And why do we need to put 1px heigth and width, and not just a “normal” size ?

Thank you very much for your answers!

S

PS : I am sorry if this question has already been asked, just didn’t find any answer.
PPS : below is the source code of the page

Source code
<head>
  <style>
  .sr-only {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px;
    top: auto;
    overflow: hidden;
  }
  </style>
</head>
<body>
  <header>
    <h1>Training</h1>
    <nav>
      <ul>
        <li><a href="#stealth">Stealth &amp; Agility</a></li>
        <li><a href="#combat">Combat</a></li>
        <li><a href="#weapons">Weapons</a></li>
      </ul>
    </nav>
  </header>
  <section>
    <h2>Master Camper Cat's Beginner Three Week Training Program</h2>
    <figure>
      <!-- Stacked bar chart of weekly training-->
      <p>[Stacked bar chart]</p>
      <br />
      <figcaption>Breakdown per week of time to spend training in stealth, combat, and weapons.</figcaption>
    </figure>
    <table class="sr-only">
      <caption>Hours of Weekly Training in Stealth, Combat, and Weapons</caption>
      <thead>
        <tr>
          <th></th>
          <th scope="col">Stealth &amp; Agility</th>
          <th scope="col">Combat</th>
          <th scope="col">Weapons</th>
          <th scope="col">Total</th>                                        
        </tr>
      </thead>
      <tbody>
        <tr>
          <th scope="row">Week One</th>
          <td>3</td>
          <td>5</td>
          <td>2</td>
          <td>10</td>
        </tr>
        <tr>
          <th scope="row">Week Two</th>
          <td>4</td>
          <td>5</td>
          <td>3</td>
          <td>12</td>
        </tr>
        <tr>
          <th scope="row">Week Three</th>
          <td>4</td>
          <td>6</td>
          <td>3</td>
          <td>13</td>
        </tr>
      </tbody>
    </table>
  </section>
  <section id="stealth">
    <h2>Stealth &amp; Agility Training</h2>
    <article><h3>Climb foliage quickly using a minimum spanning tree approach</h3></article>
    <article><h3>No training is NP-complete without parkour</h3></article>
  </section>
  <section id="combat">
    <h2>Combat Training</h2>
    <article><h3>Dispatch multiple enemies with multithreaded tactics</h3></article>
    <article><h3>Goodbye, world: 5 proven ways to knock out an opponent</h3></article>
  </section>
  <section id="weapons">
    <h2>Weapons Training</h2>
    <article><h3>Swords: the best tool to literally divide and conquer</h3></article>
    <article><h3>Breadth-first or depth-first in multi-weapon training?</h3></article>
  </section>
  <footer>&copy; 2018 Camper Cat</footer>
</body>

It doesn’t replace anything, it’s just some styles applied to an element. Like if you had a class .red { color: red; } and you added that to a paragraph element the text would be red: it “knows” because the class with those rules has been applied to that element.

If you put that class on something, it won’t be visible to someone looking at the page, because it has been placed 10,000 pixels to the left of the screen. However, it’s still in the HTML, and a screen reader doesn’t really care about styling, it’s just going to read what’s on the HTML, in order. But there is a caveat: if the element is actually completely hidden, it won’t read it; I think that’s why it’s 1px rather than 0 if I remember correctly. It’s also why you can’t just use display: none in the CSS, that will cause the screen reader to ignore it.

1 Like

I now understand better why we use it this way :slight_smile: Thank you very much for your answer @DanCouper !

1 Like