Devographics / Monorepo

Monorepo containing the State of JS apps
surveyform-sigma.vercel.app
Other
124 stars 50 forks source link

Permalink is hidden to keyboard, touch, voice users, as is its focus #270

Closed aardrian closed 9 months ago

aardrian commented 12 months ago

Describe the bug

For sections that have a permalink in the heading, it has no visible focus indicator and the icon itself remains hidden when it has focus.

Steps to reproduce the bug

  1. Using just your keyboard, navigate to any heading on the Resources page.
  2. Attempt to see the permalink icon that links to the section.
  3. Confirm it has focus via its URL displaying in the status bar.
  4. Confirm that you cannot see the icon nor any focus indicator.
  5. Hover over the heading with your mouse and confirm the icon appears as well as its focus indicator.

Expected Behavior

Actual Behavior

Related code

The permalink is made up of this elided HTML:

<div class="[…] GEisj Block__Title">
    <div […]>
        <h3 […]>
            <a class="[…] egYKUb SharePermalink […]" href="[…]" […]>
                <svg […]>
                    […]
                </svg>
                <span class="sr-only">
                    Link to section
                </span>
            </a>
            <span […]>
                Blogs &amp; Magazines
            </span>
        </h3>
    </div>
</div>

The following CSS hides the permalink by default using opacity: 0:

.egYKUb {
  float: left;
  opacity: 0;
  line-height: 1;
  width: 22px;
  margin-left: -30px;
  margin-right: 8px;
  transition: none 0s ease 0s;
  position: relative;
}

The following CSS changes the icon's opacity only when the user has used a mouse to hover over the heading's container:

.GEisj:hover .SharePermalink {
  opacity: 1;
}

Additional Context

The code as shown violates the following WCAG 2.1 Success Criterion:

Consider never hiding the icon. Visually it is a great clue to users that they can take that action at any section heading. When I first visited on mobile, I had no idea I could link a section and so had to share the page URL and instructions on where to go in the page.

A less ideal approach is to make the icon itself appear only when it has focus (but this is likely the bare minimum you need to do):

.GEisj:hover .SharePermalink,
.SharePermalink:focus {
  opacity: 1;
}

An even less ideal approach is to amend a :focus-within pseudo-class to the original selector:

.GEisj:hover .SharePermalink,
.GEisj:focus-within .SharePermalink {
  opacity: 1;
}

It will appear when keyboard users put focus on it as long as their browser supports :focus-within (I imagine it would). The catch is that testing by forcing the node to be focused in the dev tools may not trigger this, and that can make devs frowny when they don't understand why.

Voice and touch users will still not know it is there with either of these approaches, hence my suggestion to never hide it.

eric-burel commented 9 months ago

Thanks, fixed to use a 0.5 opacity, and set to 1 if the link is focused (this is done in the Permalink directly, the a tag, so no need to have a focus-within)

aardrian commented 9 months ago

@eric-burel This is a great start! Because the link is visually presented as an icon, it would fall under 1.4.11 Non-Text Contrast.

If I open the page today and only change the opacity from 0 to 0.5, then the link icon appears but its color is #524F51, only has a 1.9:1 contrast ratio with the page's background of #272325. If I change the opacity to 0.84, then I get #706D6F for the icon, which gets it to the 3:1 minimum required for WCAG conformance.