Skip to content

Accessibility: Assign proper element roles using semantic HTML or role attributes #2295

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

Closed
jhildenbiddle opened this issue Nov 1, 2023 · 4 comments · Fixed by #2304
Closed
Assignees

Comments

@jhildenbiddle
Copy link
Member

jhildenbiddle commented Nov 1, 2023

Feature request

Docsify does not use semantic HTML or assign role attributes properly. This introduces accessibility issues by preventing screen readers from identifying and navigating directly to important areas like the main content and site navigation.

Fortunately, these issues can be address easily and in a non-breaking way by assigning appropriate WAI-ARIA roles to existing elements. If breaking changes are permitted, it would be preferable to revisit Docsify's DOM structure and use of HTML tags which would reduce the need to assign role attributes.

Problem or desire

  • The <main> element is improperly used as a wrapper for the sidebar, the sidebar toggle button, and the main content. As a result, screen readers are are unable to navigate directly to the main page content.
  • The sidebar navigation acts as the site's primary navigation, however it is not rendered with a <nav> element or assigned a role of navigation. As a result, screen readers are unable to navigate directly to the site's primary navigation.
  • The top navigation is rendered using a <nav> element and no other element has been assigned a role of navigation. As a result, screen readers 1) improperly identify the top navigation as the site's primary navigation and 2) are unable to identify/navigate directly to any site navigation when the top nav is not rendered.
  • The site name/logo is contained with an <h1> element. As a result, screen readers incorrectly identify this is a level one heading instead of a site banner which typically contains the site name/logo. Rendering as an H1 also presents multiple level one headings in the document structure which, while technically valid, is confusing for users.
  • The progress bar is rendered as a <div class="progress"> element. As a result, screen readers are unable to detect or announce progress updates.
  • The cover page container lacks a meaningful role attribute. As a result, screen readers are unable to identify the type of content it contains.
  • The search plugin is rendered without role="search", does not render search progress on the screen, and uses a <div> element without role="button" as a clear button button. As a result, screen readers are unable to identify and navigate directly to the landmark search functionality, provide meaningful search progress feedback to screen readers, or indicate to screen readers that a clear button exists.

Proposal

For the main content:

  • Option 1 (non-breaking): Add role="main" to Docsify's <article id="main"> element and role="none" to the <main> element.
  • Option 2 (breaking): Move sidebar and sidebar toggle elements outside of <main> element and remove unnecessary "main" ID and wrapper elements like <section class="content">.

For the sidebar / primary navigation:

  • Add role="none" to the <aside class="sidebar"> element.
  • Option 1 (non-breaking): Add role="navigation" and aria-label="primary" to the <div class="sidebar-nav"> element.
  • Option 2 (breaking): Replace the <div class="sidebar-nav"> element with a <nav aria-label="primary"> element.

For the top navigation:

  • Option 1 (non-breaking): Add aria-label="secondary" to the <nav class="app-nav"> element.

For the site name/logo:

  • Option 1 (breaking): Wrap the site name/log in a <header> instead of <h1>, then wrap the site name/logo and the search feature within a <banner> element.

For the progress bar:

  • Option 1 (non-breaking): Add role="progressbar" and related aria attributes to the <div class="progress"> element.
  • Option 2 (breaking): Replace <div class="progress"> with a <progress> element.

For the cover page:

  • Option 1 (non-breaking): Add role="complementary" and aria-label="cover" to the <section class="cover"> element.
  • Option 2 (breaking): Replace the <section class="cover"> with <aside class="cover">

For the search plugin:

  • Add a new <div class="results-status" aria-live="polite"> element to provide search progress feedback.
  • Add aria-label="search result N" to each <div class="matching-post"> element.
  • Option 1 (non-breaking): Add role="search" to the <div class="search"> element.
  • Option 2 (breaking): See additional accessible search form guidance here: https://www.a11ymatters.com/pattern/accessible-search/.

Implementation

See above.

@jhildenbiddle jhildenbiddle self-assigned this Nov 1, 2023
@jhildenbiddle jhildenbiddle changed the title Accessibility: Proper semantic HTML or role attributes Accessibility: Assign proper element roles using semantic HTML or role attributes Nov 2, 2023
@jhildenbiddle jhildenbiddle linked a pull request Nov 16, 2023 that will close this issue
4 tasks
@trusktr
Copy link
Member

trusktr commented Nov 23, 2023

These will be really great improvements! The breaking changes would be more ideal in terms of code quality.

Maybe we can release this in such a way so that people not using versioned URLs will not get the update, by f.e. releasing the next major version on a new path? For example:

  • someone currently using //cdn.jsdelivr.net/npm/docsify will get redirected to the latest main file, which will be v4.
  • with the update, we add a console message into v4 that tells people if they want to update to v5 (or vX) they need to opt-in with a specific path, f.e. //cdn.jsdelivr.net/npm/docsify/dist/docsify.5.js
  • As we release new versions, each major release has a new path and keeps the last N versions, that way we can force people to use versions if they want to stay behind, and people who stopped maintaining their sites and didn't use versioned URLs never have a broken site.

The downside of this is that we will be publishing old and new versions. F.e. 5.0 will have 4 and 5. 6.0 will have 4, 5, and 6. Etc.

What if we just keep the last two or three versions, and delete a version after it has been logging a message to console for a year (or some time value)?

F.e. a user who currently does not use versioned URLs will start to see something like this in console:

Important! If you see this message, you are on Docsify v4 and you are not using a version number in the Docsify script URL. This script will stop being available at this location on or after Nov 22, 2024. To prevent your site from breaking, add a version to your URL like so: ....... Or better yet, update to the latest Docsify path....

@jhildenbiddle
Copy link
Member Author

jhildenbiddle commented Nov 23, 2023

These will be really great improvements!

Thanks! They're implemented and ready for review in #2304. 😄

The breaking changes would be more ideal in terms of code quality.

I opted to implement the above enhancements as non-breaking changes for the following reasons:

  1. The "breaking" options above will impact third party plugins and themes, which we want to avoid if the intention is for v5 to contain only "legacy-breaking" changes.
  2. Updating the UI (modernize, redesign, componentize) seems like a logical enhancement to target next. UI changes will obviously introduce significant breaking changes. I think the community will be better served by delivering the "breaking" accessibility enhancement along with the "breaking" UI updates in a single release (v6) instead of releasing breaking changes in two successive releases (v5 - accessibility, v6 - UI). We don't want plugin and theme authors to have to update their add-ons twice in a relatively short period of time.

I realize discussions about what comes after v5 may introduce eye rolls given how long it's taken us to get anywhere near a v5 release, but I believe we can keep the next two releases narrow in scope and release them in a reasonable time frame.

Maybe we can release this in such a way so that people not using versioned URLs will not get the update, by f.e. releasing the next major version on a new path?

Yep. Agreed. The following approach makes sense to me:

v5

Summary

  • Accessibility enhancements (non-breaking)
  • Drop legacy support (breaking)

Release details

  • New v5 CDN files available in /dist. Docs recommend @5 version lock in URLs.
  • New v4 redirect files available in /lib redirecting to @4/lib CDN files.
  • Old v4 CDN files available via @4/lib (forever).
  • Old v4 CDN files available via @latest/lib (temporary).
  • Console warning displayed when @latest Docsify CDN URL detected.

v6

Summary

Release details

  • New v6 CDN files available in /dist. Docs recommend @6 version lock in URLs.
  • Old v5 CDN files available via @5/dist (forever).
  • Old v4 CDN files available via @4/lib (forever).
  • Old v4 redirect files available in /lib redirecting to @4/lib CDN files removed.

The downside of this is that we will be publishing old and new versions. F.e. 5.0 will have 4 and 5. 6.0 will have 4, 5, and 6. Etc.

I don't think we need to worry about publishing older versions after v5 is released. The CDN handles making older versions available via URL version locks (see above). The issue we're forced to deal with for v5 is the fact that early v4 documentation recommended using @latest in the CDN URLs. Once people move to v5 using our recommended @5 URLs, we can continue publishing new major versions and existing users will be unaffected.

@trusktr
Copy link
Member

trusktr commented Nov 28, 2023

Sounds good. I think we can go with the non-ecosystem-breaking approach first, and keep good notes on how to convert that to the better format in the ecosystem-breaking change later.

I know that CDNs support versions numbers in the URLs, but for websites that have no version numbers, they'll break if we eventually remove the v4 paths. Perhaps v4 is the only file path we support for a while, and the new path will simply break people if they do not use a version number but we make that very clear in the docs.

I need to refresh on the output format and come back with a concrete plan of action for it (or do you already have one?)

@jhildenbiddle
Copy link
Member Author

...for websites that have no version numbers, they'll break if we eventually remove the v4 paths.

Right. The proposal above will break v4 sites without an @ version lock when v6 is released. That's just a suggestion. We can look at CDN statistics when the time comes to help determine if/when we remove 4v paths and redirects.

It's worth mentioning that publishing any breaking change will likely break old v4 sites since there was a time when our documentation recommended loading the latest docsify version without a version lock or a path:

<script src="//unpkg.com/docsify"></script>

This was a long time ago though and I don't know of any workarounds worth considering.

I need to refresh on the output format and come back with a concrete plan of action for it (or do you already have one?)

Haven't thought about it much, but I assume we would want to offer both an IIFE (as we do today) and an ES module.

Let's continue to conversation in Discord or a public discussion since this issue is closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants