What assistive technology is not told: row actions named alike, text kept in tooltips, links that open elsewhere, and fields without their purpose #276

Closed
opened 2026-09-18 20:34:54 +00:00 by tiagoagueda · 0 comments
Owner

From an accessibility read of the templates on 2026-09-18. axe cannot see any of it: every control has a name, every link has text; what is missing is context, purpose and the text only a hover reveals.

Row actions are named alike

documents/upload_list.html:42-49 draws "Download", "Edit", "Delete" on every row with nothing naming the row; the same shape is in applications/interview_list.html, applications/tag_list.html, jobs/industry_list.html, connections/list.html, and the sections of documents/cv_detail.html, documents/letter_detail.html and jobs/company_detail.html. SC 2.4.4 passes because the row is the context, but a links list, which is how many screen-reader users find their way round a page, reads "Edit, Edit, Edit, Delete, Delete, Delete". The bulk checkbox already does this right: jobs/partials/company_row.html:10 says "Select {name}". Fix: the same aria-label, or an sr-only suffix, on every per-row action.

Information that lives only in a title

  • jobs/partials/company_row.html:93-94: the notes column is truncate with the full text only in title.
  • jobs/industry_list.html:50: "NACE division" only in title on the code.
  • partials/plugin_tags.html:24: the provenance explanation only in title.
  • accounts/invite_list.html:48: the invitation link an administrator must hand over is max-w-xs truncate with no copy control.

A keyboard or touch user never sees a title, and a magnifier user sees an ellipsis with nowhere to go. Fix: show the text (wrap, or line-clamp-2, or a visible expansion), and a copy button for the invitation link.

applications/report.html:257 (the listing links), documents/cv_detail.html:16 and documents/letter_detail.html:15 and :42 (the previews). The other fifteen target="_blank" links carry an sr-only "opens in a new tab" or say external; these four should say the same.

The person's own fields do not say what they are for

SC 1.3.5 (identify input purpose, AA): a field collecting something about the person carries the autocomplete token that names it, so a browser can fill it and speech or cognitive tooling can recognise it. Only the telephone field has one (autocomplete="tel"). Sign-up's first and last name (accounts/forms.py:94-99) want given-name and family-name; the person's own postal address rows want address-line1, address-line2, postal-code, address-level2 and country-name; the account page's username wants username. allauth already sets email and password. A contact's or a company's fields are about somebody else and are exempt. Check: a unit test over the rendered sign-up and Your details forms.

Smaller

  • Twelve-pixel uppercase, letter-spaced headers and labels: partials/table/head.html:16-17, the sidebar labels (accounts/profile.html:27, settings/base.html:16, server/base.html:11), applications/report.html:237, core/import_csv_map.html:17 and :72, the server tables. The hardest text on the page for low-vision and dyslexic readers, and VoiceOver can spell out CSS-uppercased text letter by letter. text-xs font-medium text-ink-500 without uppercase tracking-wide reads the same and better.
  • Relative dates with no absolute one: "3 days ago" on the board card (applications/partials/application_card.html:50-52) and the backup age on the server overview; nothing in the templates uses <time datetime>. A <time> with the date in it costs nothing.
From an accessibility read of the templates on 2026-09-18. axe cannot see any of it: every control has a name, every link has text; what is missing is context, purpose and the text only a hover reveals. ## Row actions are named alike `documents/upload_list.html:42-49` draws "Download", "Edit", "Delete" on every row with nothing naming the row; the same shape is in `applications/interview_list.html`, `applications/tag_list.html`, `jobs/industry_list.html`, `connections/list.html`, and the sections of `documents/cv_detail.html`, `documents/letter_detail.html` and `jobs/company_detail.html`. SC 2.4.4 passes because the row is the context, but a links list, which is how many screen-reader users find their way round a page, reads "Edit, Edit, Edit, Delete, Delete, Delete". The bulk checkbox already does this right: `jobs/partials/company_row.html:10` says "Select {name}". **Fix:** the same `aria-label`, or an `sr-only` suffix, on every per-row action. ## Information that lives only in a `title` - `jobs/partials/company_row.html:93-94`: the notes column is `truncate` with the full text only in `title`. - `jobs/industry_list.html:50`: "NACE division" only in `title` on the code. - `partials/plugin_tags.html:24`: the provenance explanation only in `title`. - `accounts/invite_list.html:48`: the invitation link an administrator must hand over is `max-w-xs truncate` with no copy control. A keyboard or touch user never sees a title, and a magnifier user sees an ellipsis with nowhere to go. **Fix:** show the text (wrap, or `line-clamp-2`, or a visible expansion), and a copy button for the invitation link. ## Four links open a new tab without saying so `applications/report.html:257` (the listing links), `documents/cv_detail.html:16` and `documents/letter_detail.html:15` and `:42` (the previews). The other fifteen `target="_blank"` links carry an `sr-only` "opens in a new tab" or say *external*; these four should say the same. ## The person's own fields do not say what they are for SC 1.3.5 (identify input purpose, AA): a field collecting something about the person carries the `autocomplete` token that names it, so a browser can fill it and speech or cognitive tooling can recognise it. Only the telephone field has one (`autocomplete="tel"`). Sign-up's first and last name (`accounts/forms.py:94-99`) want `given-name` and `family-name`; the person's own postal address rows want `address-line1`, `address-line2`, `postal-code`, `address-level2` and `country-name`; the account page's username wants `username`. allauth already sets email and password. A contact's or a company's fields are about somebody else and are exempt. **Check:** a unit test over the rendered sign-up and *Your details* forms. ## Smaller - Twelve-pixel uppercase, letter-spaced headers and labels: `partials/table/head.html:16-17`, the sidebar labels (`accounts/profile.html:27`, `settings/base.html:16`, `server/base.html:11`), `applications/report.html:237`, `core/import_csv_map.html:17` and `:72`, the server tables. The hardest text on the page for low-vision and dyslexic readers, and VoiceOver can spell out CSS-uppercased text letter by letter. `text-xs font-medium text-ink-500` without `uppercase tracking-wide` reads the same and better. - Relative dates with no absolute one: "3 days ago" on the board card (`applications/partials/application_card.html:50-52`) and the backup age on the server overview; nothing in the templates uses `<time datetime>`. A `<time>` with the date in it costs nothing.
tiagoagueda added this to the 0.4.0 milestone 2026-09-18 20:34:54 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Postulo/postulo#276
No description provided.