Skip to content

Accessible character counter for screen readers#9009

Merged
andreslucena merged 20 commits intodecidim:developfrom
mainio:feature/a11y-character-counter
Mar 18, 2022
Merged

Accessible character counter for screen readers#9009
andreslucena merged 20 commits intodecidim:developfrom
mainio:feature/a11y-character-counter

Conversation

@ahukkanen
Copy link
Copy Markdown
Contributor

@ahukkanen ahukkanen commented Mar 11, 2022

🎩 What? Why?

This PR implements a secondary character counter that is more accessible for the screen reader users. Right now the screen reader user doesn't get any feedback on how many characters they still have left.

The general problem for just adding aria-live to the current character counter is that it would announce the updated count after every keystroke. This PR implements a method that the screen reader user only gets the "polite" announcement after every 10% of characters compared to the total amount of characters. E.g. if the maximum length is 1000, the user would get announcements for 1000, 900, 800, etc. characters left.

This is supposed to work as follows:

  • When the screen reader user enters the input, they get the announcement how many characters they have left (happens through the aria-describedby attribute)
  • When the user starts writing, they get the announcement at the given intervals as explained above
  • When the user leaves the field, the characters left is updated to the actual amount of characters left

WCAG 2.2 / 1.3.1 Info and Relationships (Level A)
WCAG 2.2 / 4.1.3 Status Messages (Level A)

https://www.w3.org/TR/WCAG22/#info-and-relationships
https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html
https://www.w3.org/TR/WCAG22/#status-messages
https://www.w3.org/WAI/WCAG22/Understanding/status-messages.html

Testing

Try out e.g. the comments field with a screen reader.

Note that the "polite" announcement also works so that the characters left won't be announced in case the user is doing something else that has more important things to announce. So be very careful to listen to the announcement just when you reach the next interval for the characters left. In other words, stop writing when you reach the interval and listen to the screen reader.

📋 Checklist

  • CONSIDER adding a unit test if your PR resolves an issue.
  • ✔️ DO check open PR's to avoid duplicates.
  • ✔️ DO keep pull requests small so they can be easily reviewed.
  • ✔️ DO build locally before pushing.
  • ✔️ DO make sure tests pass.
  • ✔️ DO make sure any new changes are documented in docs/.
  • ✔️ DO add and modify seeds if necessary.
  • ✔️ DO add CHANGELOG upgrade notes if required.
  • ✔️ DO add to GraphQL API if there are new public fields.
  • ✔️ DO add link to MetaDecidim if it's a new feature.
  • AVOID breaking the continuous integration build.
  • AVOID making significant changes to the overall architecture.

@andreslucena
Copy link
Copy Markdown
Member

@ahukkanen I think I've found a bug.

  1. Comments max length = 5546
  2. Start writing a comment so the remaining-character-count-sr changes while inspecting it with webdev tools
  3. See "4991.4 characters left". A couple of seconds later it corrects it

image

This is with Firefox 95

This fixes several issues when the user is working with the screen
reader character counter while deleting and inserting characters
in a row.
This improves the calculation of the announce threshold limit as
follows:
- If the max characters is >= 100, the announce threshold will be
  the closest "floored" hundred
- If the max characters is < 100, the announce threshold will be
  the closest "floored" ten
- Move the announce threshold calculation to the constructor not
  to calculate it on every update separately
@ahukkanen ahukkanen marked this pull request as draft March 15, 2022 14:46
@ahukkanen
Copy link
Copy Markdown
Contributor Author

@ahukkanen I think I've found a bug.

  1. Comments max length = 5546
  2. Start writing a comment so the remaining-character-count-sr changes while inspecting it with webdev tools
  3. See "4991.4 characters left". A couple of seconds later it corrects it

Thanks for testing it @andreslucena !

I have fixed the described issue by rounding (floor) the announce threshold to closest 100 if the number of characters is >= 100 and to closest 10 if below 100. So in your situation with 5546 characters, the threshold will be 500 (Math.floor(5546 * 0.1 / 100) * 100).

I also made it announce after every character when the remaining characters are 10 or less.

Which led me noticing another problem, which is why I also made it context-aware to whether the user is adding or deleting characters because it caused some weird situations when I did these in a row. I noticed this after adding the "announce after every threshold" as it would then announce "10 characters left" when I had 10 left and if I removed one, it would announce "100 characters left" before these changes.

Same issue when you e.g. had 750 characters left and then removed 100 characters, it used to announce "900 characters left" although you only had 850. So when removing characters, the next threshold would make more sense, in this situation announcing "800 characters left" in this situation.

I also tested it on NVDA and noticed that it was announcing the "characters left" twice, which did not happen e.g. with Orca. I fixed this by removing the aria-describedby attribute when the user has active focus on the element and starts to type something. The reason for the double announcement was the aria-describedby combined with the aria-live="polite" OR role="status" attribute.

I also noticed that the aria-live="polite" is unnecessary when we already have role="status", so I removed it.

After these changes, some of the tests that I wrote before will likely break and I'll still need to add few more tests, which is why I marked this as draft for now.

@ahukkanen ahukkanen marked this pull request as ready for review March 15, 2022 17:25
@ahukkanen
Copy link
Copy Markdown
Contributor Author

Tests fixed and added new tests to cover the explained cases.

Copy link
Copy Markdown
Member

@andreslucena andreslucena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍🏽

@andreslucena andreslucena merged commit b69d22a into decidim:develop Mar 18, 2022
@ahukkanen ahukkanen deleted the feature/a11y-character-counter branch March 18, 2022 09:46
@alecslupu alecslupu added this to the 0.27.0 milestone Jul 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants