Skip to content

Docs: improve a11y on section heading anchor links #41487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 25, 2025

Conversation

MaxLardenois
Copy link
Contributor

@MaxLardenois MaxLardenois commented May 23, 2025

Description

Add content in anchor-links in the section headings of the documentation. This is an accessibility improvement to vocalise the actual text of the heading on keyboard navigation.
I added 2 spans, one with .visually-hidden the other with .aria-hidden to contain the # and deleted the # added in :after pseudo-element as it was wrongly vocalized.

Motivation & Context

At the moment, the # anchor link on each section heading is vocalized as "Number" without any other precision and therefore do not provide any useful information to users of assistive technologies.

Type of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Refactoring (non-breaking change)
  • Breaking change (fix or feature that would change existing functionality)

Checklist

  • I have read the contributing guidelines
  • My code follows the code style of the project (using npm run lint)
  • My change introduces changes to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

Live previews

@julien-deramond
Copy link
Member

Thanks for tackling this issue 🙏
After the review — and for future reference — I’ll need to check the related task at #41380.

@julien-deramond julien-deramond moved this from To analyze to Needs review in v5.3.7 May 23, 2025
@MaxLardenois MaxLardenois marked this pull request as ready for review May 23, 2025 10:32
@MaxLardenois MaxLardenois requested a review from a team as a code owner May 23, 2025 10:32
@julien-deramond
Copy link
Member

The HTML and the visible focus area differ slightly from what we used in Hugo, but as long as they meet accessibility standards, it’s fine with me.

In Hugo:

<h2 id="quick-start">Quick start <a class="anchor-link" href="#quick-start" aria-label="Link to this section: Quick start"></a></h2>

In this PR:

<h2 id="quick-start">Quick start<a class="anchor-link" href="#quick-start"><span class="visually-hidden">Link to this section: Quick start</span><span aria-hidden="true"> #</span></a></h2>

Adding @patrickhlauke as a reviewer to double-check :)

@julien-deramond julien-deramond moved this from Needs review to Review in progress in v5.3.7 May 23, 2025
@MaxLardenois
Copy link
Contributor Author

MaxLardenois commented May 23, 2025

The HTML and the visible focus area differ slightly from what we used in Hugo, but as long as they meet accessibility standards, it’s fine with me.

In Hugo:

<h2 id="quick-start">Quick start <a class="anchor-link" href="#quick-start" aria-label="Link to this section: Quick start"></a></h2>

In this PR:

<h2 id="quick-start">Quick start<a class="anchor-link" href="#quick-start"><span class="visually-hidden">Link to this section: Quick start</span><span aria-hidden="true"> #</span></a></h2>

Adding @patrickhlauke as a reviewer to double-check :)

The problem I had with aria-label is that I could not get rehype to accept a function (in order to construct the label from the heading) for its properties config attribute

@julien-deramond
Copy link
Member

The problem I had with aria-label is that I could not get rehype to accept a function (in order to construct the label from the heading) for its properties config attribute

Yep, I ran into the exact same issue during the migration — that’s actually why I decided to postpone it. Really glad you found another approach though! 🙌

@MaxLardenois
Copy link
Contributor Author

MaxLardenois commented May 23, 2025

The problem I had with aria-label is that I could not get rehype to accept a function (in order to construct the label from the heading) for its properties config attribute

Yep, I ran into the exact same issue during the migration — that’s actually why I decided to postpone it. Really glad you found another approach though! 🙌

Well actually I just tested with the following code and it works now on Bootstrap code (not in our fork, we are behind)

[
  rehypeAutolinkHeadings,
  {
    behavior: 'append',
    content: [{ type: 'text', value: ' ' }],
    properties: (element: Element) => ({
      class: 'anchor-link',
      ariaLabel: `Link to this section: ${(element.children[0] as Text).value}`
    }),
    test: (element: Element) => element.tagName.match(headingsRangeRegex)
  }
],

After some investigation it turns out you updated the rehype plugin in this commit and the issue is now fixed.

I will switch to aria-label in the PR then.

@MaxLardenois MaxLardenois force-pushed the main-ml-docs-headings-a11y branch from 84f32c4 to 048b4e9 Compare May 23, 2025 14:29
@patrickhlauke
Copy link
Member

Wonderful stuff...from a quick test with Chrome/NVDA, this works fine and is a great improvement over the current # links

@julien-deramond julien-deramond moved this from Review in progress to Ready to merge in v5.3.7 May 25, 2025
@julien-deramond julien-deramond merged commit 3663e3a into twbs:main May 25, 2025
14 checks passed
@github-project-automation github-project-automation bot moved this from Ready to merge to Done in v5.3.7 May 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants