Open Jym77 opened 1 year ago
Should we elaborate on why this is "arguably worse code"? It's because an accessible name that is too long has a negative user impact, right?
Also I'd like to note a common pattern I see in the wild which triggers this issue: the "cards with large link hit areas" pattern:
<a href="https://example.com/news-for-march-16-2023">
<div style="outline: solid;">
<p style="font-weight: bold; font-size: larger">News items for March 16, 2023</p>
<p>In today's news we have Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p>
<p><i>4 minute read</i></p>
<p><i>Posted March 16, 2023</i></p>
</div>
</a>
<a href="https://example.com/news-for-march-15-2023">
<div style="outline: solid;">
<p style="font-weight: bold; font-size: larger">News items for March 15, 2023</p>
<p>In yesterday's news we have Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p>
<p><i>10 minute read</i></p>
<p><i>Posted March 15, 2023</i></p>
</div>
</a>
This pattern is advantageous for pointer users. So ideally this ACT rule and our best practices around this issue won't rule out this "cards with large link hit areas" pattern. I don't see an easy answer to this.
It seems to me this stems partly from the ambiguity of 2.5.3, specifically these phrases: "the words which visually label a component" / "the text that is presented visually".
There is way too much wiggle room there. Who determines what text "labels an element". Is this determined based on proximity to said element or the semantic logic, whether the string acts "logically" as the label.....and whose logic?
(I happen to know that in the US, a particular gov. agency came down very literally with this rule, observing the Best Practice that the name must begin w/ the visible label. They struggled mostly with the fact that Dragon only took the first id of an aria string, meaning that names really did need to "start with" the visible label, otherwise Dragon would not recognize them. This may have changed since 2020, but breaking the label in name caused actual problems for employees at the SSA.)
That said....for the first example, I can admit that what is "inside" a button that has been overridden with aria-label may not necessarily be considered the "visual label," but I don't see a systematic way of making that determination.
Me neither. This is a tough one. At AccessU last week I attended a session called "Spotting Accessibility Anti-Patterns" and the card layout was one. The instructor didn't have any slam-dunk ways to fix the card layout pattern. Only to avoid it.
Carlos, Helen and Giacomo are to set up a test environment and a survey to collect input from AT users about how much of a string match does there need to be between the programmatic label and visible piece of text on the screen
I came across a solution to Jean-Yves' original example on this issue - which, again, was this:
<button aria-label="Subscribe to newsletter" aria-describedby="label">
<span>Subscribe to newsletter</span></br>
<span style="font-size: smaller" id="label">We send 1 mail per month.</span>
</button>
Where, again, the problem is that this button fails the ACT rule "Visible label is part of accessible name" but should, allegedly, pass SC 2.5.3.
The solution is to give the button a large hit area by adding an ::after pseudo-element which covers the whole parent element. Here's a demo page I made which shows this technique for buttons. The source HTML for that demo page is this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>x</title>
<style>
div > * {
padding: .5em 1em;
margin: 0 0.5em 1em 0.5em;
flex: 0 1 20em;
border: .2em solid rgba(0,0,0,.15);
border-radius: 1em;
background-color: #fff;
}
button {
font: inherit;
background: transparent;
border: none;
}
button:focus, button:hover {
outline: none;
}
button span {
display: block;
text-align: center;
padding: .5em 1em;
margin: .5em 1em;
border: .1em solid #00c;
border-radius: .25em;
background-color: #00c;
color: #fff;
}
button:focus span, button:hover span {
color: #00c;
background-color: #fff;
}
.block-button {
position: relative;
padding: .5em 1em;
margin: 0 0.5em 1em 0.5em;
border: .2em solid rgba(0,0,0,.15);
border-radius: 1em;
}
/* This is the important part. It's what makes the clickable area large. */
.block-button button::after {
content: "";
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
</head>
<body>
<main>
<section class="block-button">
<button onclick="alert('action');">
<span>Subscribe to newsletter</span></br>
</button>
<span style="font-size: smaller">We send 1 mail per month.</span>
</section>
</main>
</body>
</html>
The above solution is a self-contained example which I created from this blog post by Adrian Roselli. It's not pretty. The equivalent solution for <a>
elements (rather than <button>
s) is simpler. Here's a demo page I made which shows this technique for <a>
elements. The source HTML for that demo page is this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>x</title>
<style>
div > * {
padding: .5em 1em;
margin: 0 0.5em 1em 0.5em;
flex: 0 1 20em;
border: .2em solid rgba(0,0,0,.15);
border-radius: 1em;
background-color: #fff;
}
a:focus, a:hover {
text-decoration: none;
}
.block-link {
position: relative;
}
/* This is the important part. It's what makes the clickable area large. */
.block-link a[href]::after {
content: "";
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.block-link:hover, .block-link:focus-within {
border-color: rgba(0,0,255,.5);
box-shadow: 0 0 .5em rgba(0,0,0,.25);
}
</style>
</head>
<body>
<main>
<div>
<section class="block-link">
<h3><a href="https://example.com/">Subscribe to newsletter</a></h3>
<span style="font-size: smaller">We send 1 mail per month.</span>
</section>
</div>
</main>
</body>
</html>
Credit also to Tero Pesonen, which was the first to show this technique to me, on his demo page (under the "composites" tab). Tero's demo page doesn't use ::after, but it amounts to the same thing.
This pattern is often called the "block link" pattern or "card" pattern. Tero called it the "linkbox" pattern. This technique for dealing with the pattern is called "the pseudo-content trick" (at least by Heydon Pickering on this page.)
"The pseudo-content trick" has a shortcoming: you can't select any of the text on the card any more. Regardless, I think it's a pretty good way to make the "block link" pattern pass SC 2.5.3 and the ACT rule "Visible label is part of accessible name", while having a good and short accessible name.
It passes the ACT rule today. (It doesn't require any changes to the rule.) So maybe I'll add propose adding a "passed example" to the rule which shows this technique.
Visible label is part of accessible name compares the visible text content of a widget with its accessible name, it maps to 2.5.3 which compares the "label" with the name, where "label" is used in the generic WCAG sense of the term.
Now, I've seen cases that look like:
This
button
fails the rule because the accessible name "Subscribe to newsletter" does not contain the visible text content "Subscribe to newsletter We send 1 mail per month." I am, however, not convinced that it should fail 2.5.3 🤔This essentially boils down to define what WCAG calls "label" and what is the "label" in this case. The Understanding document of 2.5.3 has some discussion (second to last paragraphs of "Intent") about the fact that "label" should be interpreted fairly strictly for this SC, notably:
Similarly, Technique G211, which is sufficient for 2.5.3, has this example of stacked labels (edited with style):
Where the intermediate text is not part of the "label". It is fairly easy to tweak it and move the description inside the
label
element:While this is arguably worse code, this is essentially the same thing as the example in G211 previously and should therefore satisfy 2.5.3. Now, this is not Applicable for the rule, but it seems to indicate that WCAG consider "label" to be the "main label", not necessarily the full thing with extra indication, and therefore I think the
button
at the start of this issue should satisfy 2.5.3, but fails the rule 💥