When designing a page, in order to improve the user’s clickable experience, there is a need to expand the clickable area of an element — the element we see is small, but the actual clickable area is large. For example, wrapping a large piece of content around a tag so that clicking on any part of the area will jump is what we call a “block link.” It’s functionally fine, but it doesn’t take into account the experience of screen readers.

Adrian Roselli, author of Block Links, Cards, Clickable Regions, Etc., discusses this topic and offers solutions. Simply put, don’t use or

a::after.button::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}
Copy the code

Not only is it effective, but it’s also screen friendly.

If you are interested in details, you can continue to read my translation of the text below ~~

link

Using to wrap a block link around all content implementations is probably the least desirable.

For example, the following code:

<article>
  <a href="https://example.com/linkwrap" rel="nofollow">
    <h3>Wrapping Entire Thing</h3>
    <img src="https://www.fillmurray.com/640/360" alt="Bill Murray on the award carpet.">
    <p>
      Gastropub sartorial ... affogato bicycle rights.
    </p>
  </a>
</article>

<style>
a:link {
	text-decoration: none;
}
</style>
Copy the code

If the tag here is not set to display: block, there will be a problem.

As you can see, the cursor does not always hover over the link (marked by the appearance of an underscore). There are click dead zones around the text, between the picture and the text, which is easy to hover over links to different addresses. Similarly, underlining entire paragraphs makes it harder to read; If none are underlined, the click hints are cut.

To make things worse, the screen reader will read the entire text (including the title, image (it won’t tell you it’s an image yet, just read its Alt) and the text block), and then tell you “link” (the type of tag) when it’s finished.

Tabbing through the links in Firefox 72 with NVDA 2019.3.1.


Here is the structure of the other two types of links:

<! -- Second example -->
<article style="position: relative;">
  <h3><a href="https://example.com/heading">Only on Heading</a></h3>
  <img src="https://www.fillmurray.com/600/380" alt="Bill Murray in a still from Caddyshack.">
  <p>   
		Tumeric prism tattooed ... slow-carb unicorn.
  </p>
</article>

<! -- Third example -->
<article style="position: relative;">
  <a href="https://example.com/linkwrap" rel="nofollow">
    <h3>Wrapping Entire Thing</h3>
    <img src="https://www.fillmurray.com/640/360" alt="Bill Murray on the award carpet.">
    <p>
      Sriracha actually ... party flannel. 
      <a href="https://example.com/text" rel="nofollow" aria-describedby="A3">Read more...</a>
    </p>
  </a>
</article>

<style>
  a[href]::after {
    content: "";
    The element pos absolute is a block element, and the block element is absolute
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
  }
</style>
Copy the code

One link is wrapped in

and the other is wrapped in the paragraph element

. The third example I used aria-describedby to refer to < H3 >. These two types of links are the solution we’ll be looking at today — namely positoin: Ablsolute fills the entire card space with the clickable range of links, which may not be the best solution, of course.

Speaking of which, there is a misconception among developers that screen reader users only use the Tab key to view content on a page, forgetting that arrows (or swipes on touch devices) are actually the main way.

Here is an example of what the content looks like using arrow.

Arrowing through the content in Firefox 72 with NVDA 2019.3.1.

For the first type of link, screen readers declare each piece of text as a link, which can easily confuse the user as to whether they all refer to the same link. Perhaps only an experienced user can tell that they all refer to the same place. Relatively speaking, the latter two block link effect is relatively good.

The CSS implementation of block linking is relatively simple:

a[href]::after {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
Copy the code

Note that this approach implements block chaining that prevents text selection.

Heydon Pickering makes a similar discussion of what’s going on here in his article Inclusive Components of Cards, without giving an example of a screen reader.

variant

I’m often asked about two challenges with this approach. One is Content Order and another is Additional Controls.

Content of the order

I think it’s best to use a title to organize content (everything that follows is a description of that title), and some developers may not know how to mark designs that visually have images above the title. In essence, images such as those appearing in the card component serve the title and text context of the card. Therefore, structurally I always put the title first in the component in order to focus on the content.

So how do you get ahead of the curve visually? I’ll use the Order property of the Flex project, which is one of the few use cases I advocate for using CSS to reorder content for visual design purposes.

.card {
  display: flex;
  flex-direction: column;
}

.card img {
  order: -1;
}
Copy the code

Additional controls

If you need to add additional links, buttons, or other controls to the card, place them at the bottom or top of the card (or even along the sides). This can also be done by reserving space. The code looks like this:

a[href]::after {
  bottom: 3.75 em;
}

/* the  in the 

tag does not need to expand the clickable area */

p a[href]::after { content: none; } Copy the code

The effect is as follows:

The developer tool shows the clickable area of the block link, with some white space at the bottom

We left some white space under the image to help avoid accidentally clicking/tapping on the content of the link above.

button

Much of what you learned above also applies to the

Unlike tags, you can nest headings, lists (however small), and other elements in

Take the following code for example:

<button type="button" onclick="alert('You look nice in those shoes.');" > <h3>Wrapping Entire Thing</h3> <p> Hundreds of ... pale blue dot? </p> <p> <span>Settings</span> </p> </button> <section style="position: relative;" > <h3>Only on Settings Text</h3> <p> Hundreds of ... pale blue dot? </p> <button type="button" class="btn" onclick="alert('You look nice in that shirt.');" > <span>Settings</span> </button> </section> <style> .btn::after { content: ""; display: block; position: absolute; top: 0; bottom: 0; left: 0; right: 0; } </style>Copy the code

Screen reader reading effects are as follows:

Tabbing through the buttons in Safari with VoiceOver on macOS.

Here is what

Screen readers may be satisfied with a control that only reads “Settings”. Even if you feel confused, the process of going back or jumping to the previous title to get the context you need is simple and quick.

The block link style described above applies here as well. The same applies even if the button contains an image or some other control.

Demo

All of the sample code described above can be found in the Codepen notes below, and you can click to see the code in action, or you can debug it using your own mock assistive environment.

Codepen. IO/aardrian/PE…

(End of text)


Advertising time (long term)

I have a good friend who owns a cattery, and I’m here to promote it for her. Now the cattery is full of Muppets. If you are also a cat lover and have the need, scan her FREE fish QR code. It doesn’t matter if you don’t buy it. You can just look at it.

(after)