Repository navigation
Accessibility: Assign proper element roles using semantic HTML or role attributes #2295
Copy link
Copy link
Closed
Labels
Description
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 aroleofnavigation. 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 aroleofnavigation. 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
roleattribute. 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 withoutrole="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 androle="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"andaria-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"andaria-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.
Reactions are currently unavailable
Activity
[-]Accessibility: Proper semantic HTML or `role` attributes[/-][+]Accessibility: Assign proper element roles using semantic HTML or `role` attributes[/+]trusktr commentedon 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:
//cdn.jsdelivr.net/npm/docsifywill get redirected to the latest main file, which will be v4.//cdn.jsdelivr.net/npm/docsify/dist/docsify.5.jsThe 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:
jhildenbiddle commentedon Nov 23, 2023
Thanks! They're implemented and ready for review in #2304. 😄
I opted to implement the above enhancements as non-breaking changes for the following reasons:
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.
Yep. Agreed. The following approach makes sense to me:
v5
Summary
Release details
/dist. Docs recommend@5version lock in URLs./libredirecting to@4/libCDN files.@4/lib(forever).@latest/lib(temporary).@latestDocsify CDN URL detected.v6
Summary
Release details
/dist. Docs recommend@6version lock in URLs.@5/dist(forever)./libredirecting to@4/libCDN files removed.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
@latestin the CDN URLs. Once people move to v5 using our recommended@5URLs, we can continue publishing new major versions and existing users will be unaffected.trusktr commentedon 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 commentedon Nov 29, 2023
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:
This was a long time ago though and I don't know of any workarounds worth considering.
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.