Web Accessibility learned, the hard way...
Tags: a11y
Published: 2022-01-04 08:17:55

This post is going to be my ever updating journal to record many learnings which I learned by implementation, from peers, some hints from blogs, sites etc. Main intent is to record everything that is not available in stackoverflow and links for everything available in stackoverflow for reference on `a11y`.

**Screen readers used**:
- Voiceover (iOSv15)
- Android Talkback

## Cookbook recipes
#### List item element receiving focus, announcing "bullet"
CSS can help fix this issue by saying `list-style-type: none`

#### Link vs Button on pages
When we have a user action causing redirection/navigation to another URL, the `role` should be `link`. But in cases where the user actions is causing pop-ups etc, it should be `button`.

#### Using flexbox to prevent screen-reader focus
I have not come across any articles explaining this, but when we have the children as `flexbox`, the screen-reader just focuses on parent container. If you have `aria-label` on the parent to `flexbox`, it reads it. Else falls back to reading the contents combined.
{% codepen https://codepen.io/snow650/pen/qBPKbQK %}

#### Removing `tabindex` for talkback to prevent focus
In Android, when we have `tabindex` set, it becomes eligible for receiving focus, irrespective of its value. So, its text contents are read. Removal of that attribute prevents the focus.

#### Announcing status or toast updates
##### using HTML attributes
This method involves creating a `live-region` and setting politeness for announcing the alerts.

##### using JS
This itself involves having multiple approaches. One of them is to create a singleton placeholder and push content inside this region. The attributes like `aria-hidden`, `aria-live` etc needs to be set and this can be unset after some fixed/dynamic timeout duration.

#### Focus elements on page load in voiceover in Javascript
[This is the best](https://linkedlist.ch/setting_voiceover_focus_with_javascript_17/) I have come across to achieve this. Tried using various `focusInterval` with `setTimeout` instead of `setInterval` but faced certain drawbacks each time.
When `30ms` is used with `setTimeout`, focus was missing for some cases. With `50ms`, the default focus announces an element followed by shift in focus to read the current one.

## Understanding screen reader behaviours
#### `tabindex` interpretation
{% codepen https://codepen.io/snow650/pen/MWERYbJ %}
In the codepen above, various scenarios of `tabindex` are added on both parent and child. In `voiceover` the `tabindex` attributes are not considered much and screen-reader focuses mainly on presence of text/content rather than the attribute. Whereas for `talkback`, based on how we specify the `tabindex` the behaviour changes drastically. Example:
- **When we have `tabindex` only on parent**: the focus does not come to the child element since the parent already has the attribute.
- **When both parent and child has the attribute**: the focus comes to both of them and inner content read repetition happens.
- **When there in attribute only on child**: it is equivalent of no attribute because the child being a text node, it will naturally receive the focus.
- **No attribute anywhere**: same as case 3