Accessible 'read more' links

For example: Read more

<a href="page.html">Read more</a>

At the end of a component often there is a link with (English) text like 'Buy now', 'Read more', 'Read more', etc. These have some accessibility issues.

Link text (accessible name)

The link text for ‘Read more’ does not provide enough context to the user of a screen-reader who may be navigating a page via a list of links.

We want to hijack this ‘accessible name’ of ‘Read more’ and provide more context.

There are four approaches we recommend and one we don’t…

And before we start with the technical approaches, it's important to say, the best solution is to change the 'call to action' from 'Read more' to something more contextual. Good call to actions

Approach 1 - link a heading instead

This technique is great but it involves a lot of HTML+CSS knowledge and will only be appropriate in certain situations.

Bad example

<div class="card">
  <h2>Card title</h2>
  <p>Extra wording inside the card.</p>
  <a href="page.html">Read more</a>
</div>

Good example

<div class="card">
  <h2><a href="page.html">Card title</a></h2>
  <p>Extra wording inside the card.</p>
  <a aria-hidden="true" href="page.html" tabindex="-1">Read more</a>
</div>

In the 2nd example we have taken the read more link out of the accessibility tree by hiding it from screen-readers via aria-hidden="true" and preventing keyboard users tabbing to it by adding tabindex="-1" to it. We have also wrapped a link around our 'Card title' text. The assumption in this card pattern that the 'Card title' is unique and contextual.

Approach 2 - use aria-describedby

Add an id to the relevant heading and reference it on the Link (a) with an aria-describedby attribute e.g.

<div class="card">
  <h2>Card title</h2>
  <p>Extra wording inside the card.</p>
  <a aria-describedby="unique-id" href="page.html">Read more</a>
</div>

With this approach, the screen-reader will read out ‘Read more (PAUSE) Card title’.

useUniqueId

With aria-describedby an issue can be generating unique ids. If you are using React, you can usethe hook useId from React 18 but note this should not be used inside a loop becasue every item inside the loop will have the same id.

Approach 3 - use a 'hidden' span

You could add a span element styled to only be visible to screen-readers.

<div class="card">
  <h2>Card title</h2>
  <p>Extra wording inside the card.</p>
  <a href="page.html">
    Read more
    <span class="visually-hidden"> - Card title</span>
  </a>
</div>

View the CSS behind .visually-hidden

In this approach, the screen-reader will read out ‘Read more - Card title’. It may update how the link is communicated when the user is navigating the page via a list of links too.

Note: This approach is preferred over approach 3 (using an aria-label) because in our links that open in new windows/tab we add hidden text to inform users of that fact. If we use aria-label on these links it will not read out the 'opens in new window' help text.

Approach 4 - use aria-label

Provide an aria-label attribute on the Link component e.g.

<div class="card">
  <h2>Card title</h2>
  <p>Extra wording inside the card.</p>
  <a aria-label="Read more about Card title" href="page.html">Read more</a>
</div>

The issue with aria-label is that it will not be automatically translated for anyone who uses their browser to translate the page i.e. not going through the different language versions of your translated site but using Google Translate inside Chrome itself.

With this approach, the screen-reader will read out ‘Read more about Card title’. It may update how the link is communicated when the user is navigating the page via a list of links too.

It is more likely you will code it like this:

const title = 'Card title";
const linkText = 'Read more";

<div class="card">
  <h2>Card title</h2>
  <p>Extra wording inside the card.</p>
  <h2>{title}</h2>
  <a aria-label={`${linkText} - ${title}`} href="page.html">{linkText}</a>
</div>

This will read out Read more - Card title and so it fulfils the criteria that the aria-label should contain the innerText of its element whilst also adding extra context for screen-reader users.

Approach 5 - title (not recommended)

If you place a title attribute on the link, a little tooltip will appear on hover. This is not helpful for keyboard users, for whom, it won’t be seen nor screen-reader users for whom it won’t be read out.

<div class="card">
  <h2>Card title</h2>
  <p>Extra wording inside the card.</p>
  <a href="page.html" title="Card title">Read more</a>
</div>

Further reading

  1. The endless search for 'here' in the the unhelpful 'click here' button
  2. Better accessible names
  3. Tailwind CSS accessibility - .sr-only class
  4. Change Chrome languages and translate web pages
  5. useId ReactJS docs
  6. TPGI - The anatomy of visually-hidden

Want to work with us?

Let’s talk about your project