Deck 6 - Accessibility + Semantics + ARIA Flashcards

Semantic HTML, labeling/names, keyboard support, focus management (dialogs), and ARIA states without over-ARIA (80 cards)

1
Q

Deck 6 - Accessibility + Semantics + ARIA (objective)

A

Goal: spot and fix a11y/semantic issues (WCAG-minded) without over-ARIA.
You practice: semantic HTML, labeling, keyboard support, focus management, and ARIA patterns.
Output style: 1 verdict sentence + 2-3 issues + safest fix approach.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

A11y baseline rule (most important).

A

Use semantic HTML first; add ARIA only to fill gaps. Avoid role overrides that break native semantics.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

WCAG in practice (what evaluators look for).

A

Keyboard access, visible focus, proper labels/names, correct roles/states, readable structure, and announced async changes.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Accessible name (definition).

A

The label screen readers use for a control. Sources: <label>, aria-label, aria-labelledby, and sometimes text content.</label>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Labeling inputs (best practice).

A

Prefer <label>. Alternatives: aria-label or aria-labelledby. Placeholder is not a label.</label>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Buttons vs divs (rule).

A

Clickable UI should be <button> (or <a>) not <div onClick>. If custom, must add role, tabIndex, and keyboard handlers.</a></button>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Links (rule).

A

Use <a> for navigation, <button> for actions. Do not use <a> for actions.</a></button></a>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Headings (structure).

A

Use h1-h6 in order to create a logical outline. Do not skip levels for styling.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Lists and tables (semantics).

A

Use <ul>/<ol>/<li> for lists. Use tables for data grids, with proper <th scope> and captions when needed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Images (alt text).

A

Meaningful images need alt text; decorative images should use alt=’’ and aria-hidden=’true’ when appropriate.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

ARIA roles (when to use).

A

Use ARIA roles for custom widgets only. Do not add role=’button’ to <button>, role=’link’ to <a>, etc.</a></button>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

aria-* states (common).

A

aria-expanded for toggles, aria-pressed for toggle buttons, aria-selected for tabs/options, aria-disabled (avoid if native disabled works).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Keyboard interaction patterns (baseline).

A

Enter/Space activate buttons; arrow keys for menus/tabs; Escape closes popovers/modals; Tab moves focus.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Focus management (common).

A

On open: move focus into modal/popover. On close: restore focus. Trap focus in modal. Avoid focus loss on rerenders.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Dialogs/modals (baseline).

A

Use role=’dialog’ with aria-modal=’true’, label via aria-labelledby, and focus trap/restore.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Live regions (async updates).

A

Use aria-live=’polite’ for non-urgent updates; role=’alert’ for errors. Keep messages concise.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Form validation messaging.

A

Associate errors with inputs (aria-describedby). Use aria-invalid when invalid. Do not rely on color alone.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Disabled vs aria-disabled.

A

Prefer native disabled (removes from tab order). aria-disabled keeps focusable; use only when needed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Avoiding duplicate IDs (React).

A

IDs must be unique. Use useId() for stable unique IDs across server/client rendering.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Testing a11y basics (RTL).

A

getByRole + name is an a11y assertion. Ensure elements are reachable and labeled; role=alert for errors.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Gotcha: clickable div without keyboard.

function X() {
  return <div onClick={save}>Save</div>;
}
A

Verdict: FAIL
- Issue: non-semantic interactive element; not keyboard accessible.
- Fix: use <button>Save</button> (or implement role+tabIndex+keys if custom).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

Gotcha: missing label for input.

<input id='q' placeholder='Search' />
A

Verdict: FAIL
- Issue: placeholder is not a label.
- Fix: add <label>Search</label> or aria-label.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

Gotcha: label not associated.

<label>Search</label>
<input id='q' />
A

Verdict: FAIL
- Issue: missing htmlFor.
- Fix: <label>Search</label>.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

Gotcha: button missing type in a form.

<form>
  <button onClick={onCancel}>Cancel</button>
</form>
A

Verdict: PARTIAL FAIL
- Issue: default type is submit.
- Fix: type=’button’ for non-submit buttons.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Gotcha: anchor used for action. ``` Logout ```
Verdict: FAIL - Issue: wrong semantics for action. - Fix: .
26
Gotcha: icon-only button has no name. ``` ```
Verdict: FAIL - Issue: missing accessible name. - Fix: add aria-label='Close' or visible text.
27
Gotcha: aria-label conflicts with visible text.
Verdict: PARTIAL FAIL - Issue: inconsistent accessible name. - Fix: align aria-label with visible label or remove it.
28
Gotcha: role='button' on native button. ``` ```
Verdict: PARTIAL - Issue: redundant ARIA. - Fix: remove role and rely on native semantics.
29
Gotcha: custom control missing tabIndex. ```
Save
```
Verdict: FAIL - Issue: not focusable via keyboard. - Fix: prefer
30
Gotcha: aria-hidden contains focusable control. ``` ```
Verdict: FAIL - Issue: hidden content should not be focusable. - Fix: do not hide interactive elements this way.
31
Gotcha: duplicate ids. ``` ```
Verdict: FAIL - Issue: duplicate ids break label wiring. - Fix: unique ids; use useId() for lists.
32
Gotcha: missing aria-expanded on disclosure. ``` {open &&
...
} ```
Verdict: PARTIAL - Issue: state not announced. - Fix: aria-expanded={open} aria-controls='panel'.
33
Gotcha: aria-controls references missing id. ```
...
```
Verdict: PARTIAL FAIL - Issue: aria-controls points to missing target. - Fix: set id='panel' on controlled region.
34
Gotcha: custom checkbox without keyboard. ```
X
```
Verdict: FAIL - Issue: not tabbable; no Space toggle. - Fix: prefer native checkbox or add tabIndex=0 + onKeyDown Space.
35
Gotcha: aria-disabled instead of disabled. ``` ```
Verdict: FAIL - Issue: still clickable. - Fix: use disabled and block handler.
36
Gotcha: focus outline removed in CSS.
Verdict: FAIL - Issue: invisible focus indicator. - Fix: keep :focus-visible styles.
37
Gotcha: modal missing role/label/focus. ``` {open &&
...
} ```
Verdict: FAIL - Issue: missing dialog semantics and focus management. - Fix: role='dialog' aria-modal + aria-labelledby; trap/restore focus.
38
Gotcha: no focus restore on close.
Verdict: FAIL - Issue: keyboard users lose place. - Fix: restore focus to trigger element on close.
39
Gotcha: positive tabindex used.
Verdict: PARTIAL FAIL - Issue: breaks natural tab order. - Fix: avoid positive tabindex; use 0/-1 only when needed.
40
Gotcha: input error not associated. ```
Invalid email
```
Verdict: PARTIAL FAIL - Issue: helper not linked. - Fix: aria-describedby='emailHelp' and aria-invalid when invalid.
41
Gotcha: aria-invalid always true.
Verdict: PARTIAL FAIL - Issue: announces invalid always. - Fix: set conditionally.
42
Gotcha: error message not announced. ``` {error &&
{error}
} ```
Verdict: PARTIAL - Issue: not announced. - Fix: role='alert' for error region.
43
Gotcha: aria-live used for large content.
Verdict: PARTIAL FAIL - Issue: SR spam. - Fix: announce only status text, not whole content.
44
Gotcha: placeholder-only form. ``` ```
Verdict: FAIL - Issue: missing label. - Fix: label/aria-label.
45
Gotcha: headings skipped. ```

Title

Section

```
Verdict: PARTIAL FAIL - Issue: heading structure. - Fix: use h2 for next level; style via CSS.
46
Gotcha: list rendered as divs. ```
Item 1
Item 2
```
Verdict: PARTIAL FAIL - Issue: missing list semantics. - Fix:
  • ...
.
47
Gotcha: image missing alt. ``` ```
Verdict: FAIL - Fix: add descriptive alt or provide text alternative.
48
Gotcha: decorative image has noisy alt. ``` decoration ```
Verdict: PARTIAL - Fix: alt='' for decorative images.
50
Gotcha: invalid ARIA role value.
Verdict: FAIL - Issue: invalid ARIA. - Fix: use valid roles only; prefer semantics.
51
Gotcha: table missing headers for tabular data.
Verdict: PARTIAL FAIL - Fix: use where applicable.
52
Gotcha: checkbox uses onKeyPress (deprecated).
Verdict: PARTIAL FAIL - Fix: use onKeyDown and handle Space/Enter.
53
Gotcha: button has no visible focus styles due to outline: none.
Verdict: FAIL - Fix: provide visible focus ring (focus-visible).
54
Gotcha: error message color-only indicator.
Verdict: PARTIAL FAIL - Fix: include text/icon and programmatic cues (aria-invalid, describedby).
55
Gotcha: aria-describedby points to missing id.
Verdict: PARTIAL FAIL - Fix: ensure describedby id exists in DOM and is unique.
56
Gotcha: landmark missing main region.
Verdict: PARTIAL - Fix: wrap primary content in
.
57
Gotcha: useId not used for SSR-safe ids (when SSR present).
Verdict: PARTIAL - Fix: use useId() for stable unique ids.
58
Gotcha: custom tabs missing roles/keyboard.
Verdict: FAIL - Fix: implement tablist/tab/tabpanel roles + arrow-key nav, or use a library.
59
Gotcha: aria-expanded set on wrong element.
Verdict: PARTIAL FAIL - Fix: put aria-expanded on the toggle button that controls the panel.
60
Gotcha: aria-modal missing on dialog.
Verdict: PARTIAL - Fix: aria-modal='true' (plus focus trap).
61
Scenario: verdict + 3 issues. ``` return (
); ```
Verdict: FAIL 1) non-semantic interactive element 2) not keyboard accessible 3) missing accessible name; use
62
Scenario: best fix for icon-only Close button.
Use
63
Scenario: placeholder vs label.
Placeholder is not a label. Provide
64
Scenario: role='alert' vs aria-live='polite'.
Use role='alert' for errors/urgent messages; aria-live='polite' for non-urgent status updates.
65
Scenario: disclosure toggle for panel.
Use
66
Scenario: custom checkbox minimum.
tabIndex=0; Space toggles; role='checkbox' + aria-checked; prefer native checkbox when possible.
67
Scenario: modal essentials.
role='dialog', aria-modal='true', labeled (aria-labelledby), focus in, trap focus, restore focus on close.
68
Scenario: validation message wiring.
Render error with id; set aria-describedby to that id; set aria-invalid when invalid.
69
Scenario: headings for styling only.
Use correct heading levels for structure; style with CSS (do not skip levels).
70
Scenario: meaningful vs decorative images.
Meaningful: descriptive alt. Decorative: alt='' (and optionally aria-hidden).
71
Scenario: why getByRole in tests helps a11y.
It enforces correct roles and accessible names; catches unlabeled or non-semantic widgets.
73
Scenario: focus outline removed - one-liner.
FAIL - Removing focus indicators breaks keyboard navigation; keep visible focus (use :focus-visible).
74
Scenario: duplicate ids in repeated fields.
Generate unique ids per item (useId or stable ids) so labels associate correctly.
75
Scenario: one-liner for over-ARIA.
PARTIAL FAIL - ARIA is used where native semantics already apply; remove redundant roles and rely on semantic HTML.
76
Checklist: a11y review top 5.
1) Semantic HTML first 2) Keyboard support 3) Accessible names 4) Focus management for dialogs 5) Announce errors/status (alert/live)
77
Checklist: labeling quick rules.
78
Checklist: common ARIA states.
aria-expanded aria-pressed aria-selected aria-invalid aria-describedby
79
Checklist: modal essentials.
role='dialog' + aria-modal aria-labelledby focus in trap focus restore focus
80
Checklist: evaluator wording for a11y issues.
Name issue (non-semantic/unlabeled/not keyboard), impact (inaccessible), fix (semantic element + label + focus/ARIA).