rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.81k stars 12.77k forks source link

Rustdoc search box fails accessability guidelines #31060

Open steveklabnik opened 8 years ago

steveklabnik commented 8 years ago

Background links: https://www.w3.org/TR/WCAG20-TECHS/H32.html for a11y, http://doc.rust-lang.org/std/ for rustdoc search. Before typing anything:

2016-01-20-141055_981x72_scrot

After typing a query:

2016-01-20-141108_968x198_scrot

Basically, we currently implement the searchbox by using JS to hook into the submission: https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/main.js#L737-L741

So we're not providing a 'submit' button. But we're supposed to.

I'm not sure of the best way to resolve this, exactly. I think the plan would be:

  1. create an <input type="submit">
  2. hide it with CSS
  3. have it trigger that JS instead

Does that make sense? I am bad at front-end :(

nagisa commented 8 years ago

I believe we already handle the submit events properly (I made it to do so) and pressing the Enter delivers such an event. I’m not sure how adding a hidden button would change anything here, but if that makes some a11y testing suite happier, sure?

marcysutton commented 8 years ago

A few tweaky things you could do, to start:

  1. Add a label to the input field, either using a paired label element or an aria-label attribute directly on the input.
  2. Mark up the results table so the columns relate to each other. OR change the markup into a list of links using CSS to style them instead.

For the results experience, you have a few options. Without a submit button it acts like an autocomplete, which can be a complex ARIA pattern to master. Essentially, you'd use an ARIA live region to announce there are results on the screen, and bind the arrow keys to navigate the results nearby. But I think if you added a submit button you could get away with skipping the autocomplete functionality, since the user will expect results. To make things slick you could use focus management to send focus into the results after submitting.

Hope that helps!

onelson commented 7 years ago

I spent a little while looking at the markup and js in play here, and while it would be trivial to add a submit input which is hidden, it also feels a bit like following the letter of the law while neglecting the spirit.

I am not up to speed on ARIA mechanics, but skimming through https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions made me feel like @marcysutton is right on the money. The flow described here looks to line up very well with how search results behave.

In order to decide if it would be worth the extra effort I got a screen reader and enabled while searching the docs. The results were illuminating!

With an added submit input, it appears we earn nothing over what we already have. The content of the search box is read aloud as the search terms are typed, but there's no indication that results have been loaded after the fact.

I looked at a few examples of how live regions are meant to work, and made the following changes as a test:

diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 8c14d1bbe8..51e88c5bb0 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -72,7 +72,7 @@ r##"<!DOCTYPE html>
     <nav class="sub">
         <form class="search-form js-only">
             <div class="search-container">
-                <input class="search-input" name="search"
+                <input class="search-input" name="search" aria-controls="search"
                        autocomplete="off"
                        placeholder="Click or press ‘S’ to search, ‘?’ for more options…"
                        type="search">
@@ -81,7 +81,7 @@ r##"<!DOCTYPE html>
     </nav>

     <section id='main' class="content">{content}</section>
-    <section id='search' class="content hidden"></section>
+    <section id='search' class="content hidden" role="alert" aria-live="polite"></section>

     <section class="footer"></section>

With the search input listed as something that controls the live region the results are rendered in, my typing was read aloud as I entered my terms, then as the results loaded in the reader announced:

This is just the visible text inside the search node in the DOM, but it felt like an immediate improvement. When I resumed typing, the process started again from the top once I gave it a beat to interrupt.

This seems more useful, but examining some other examples of autocompletion widgets, I think we can do better.

One implementation I saw used a hidden span as the live region and updated its content with status and instructional text. In that case, the span would announce the number of results and instructions to use up/down to select an item from the list.

For us, I can imagine using a hidden span to report the number of results, total and for each column, what the active column is, then instruct the user to use up/down and also note that tab would switch columns. As the user navigates the list, the span could be updated with the text content of the result. This is exactly what Marcy was pitching, if I understand correctly.

This offers a couple wins over the initial test I did in that it's more instructional, it helps the user keep track of what state the page is in, and it saves the user from a rambling recital of all the visible results - instead the results are read at a pace controlled by the user themselves.

As an aside, using tab to switch the active column felt a little weird to me. I wonder if we couldn't listen to a different key press for switching the active result type. Maybe h/l for the vim crowd, or left/right (which seems better to me). For this to work, we'd have to pull focus from the search input while navigating the results, which would be a change from how it currently works. This could really offend folks used to the old behavior.

I'm no accessibility expert. I'm coming to this fresh. Still, if this sounds like a good plan to others, I'm happy to dig in and try to make it happen.

nrabulinski commented 4 years ago

@rustbot claim

Alexendoo commented 4 years ago

Hi, are you still working on this issue @nrabulinski?

Alexendoo commented 4 years ago

@rustbot release-assignment

jsha commented 3 years ago

using tab to switch the active column felt a little weird to me. I wonder if we couldn't listen to a different key press for switching the active result type. Maybe h/l for the vim crowd, or left/right (which seems better to me). For this to work, we'd have to pull focus from the search input while navigating the results, which would be a change from how it currently works. This could really offend folks used to the old behavior.

FYI, in #84462 we recently did this. After searching, you can use the down arrow to focus the results area, and then you can use left/right to focus different result tabs.