Problem/Motivation
Entering office hours gives screenreader users a hard time. Let's pick at least the low-hanging fruit.
- The all-day checkbox is too verbose (visually hidden label reads "Indicates if the entity is opened all day")
- The time fields are too verbose (and contain more attributes than necessary)
- First column in table is no heading, thus will not be announced (instead of "Monday" it reads "second row")
- Action links have an empty href attribute, no aria attributes and provide no feedback (semantically should be buttons)
- "From - to" range translates inappropriately generic to other languages
Steps to reproduce
I am focusing on the widget Office hours (week) with exceptions and seasons here.
- Add an office hours field to any node bundle
- Configure Time element type: HTML5 time input
- Configure Time notation: 24 hours
- Enable "Allow 'all day' situations
- Enable "Allow exception days
- Enable "Allow seasons
- In form display, choose "Office hours (week) with exceptions and seasons" widget
View mode with different configurations seemed good to me, skipping for now.
Proposed resolution
Low-hanging
- All-day checkbox label: change "Indicates if the entity is opened all day" to "Open all day"
- Change HTML5 time field markup (see below)
- First column in table body: change
<td> ... </td>to<th> ... </th> - Add a time span-related context for "From" and "to" strings
HTML time field markup
Given:
<input
data-drupal-selector="edit-field-office-hours-office-hours-0-value-12-starthours-time"
type="time"
step="60"
title="Time, with an increment of 1 minute (e.g. 17:25)"
placeholder="hh:mm:ss"
data-help="Enter the time using the format hh:mm:ss (e.g., 17:19)."
id="edit-field-office-hours-office-hours-0-value-12-starthours-time"
name="field_office_hours[office_hours][0][value][12][starthours][time]"
size="12"
class="form-time form-element form-element--type-time form-element--api-date"
data-once="field-group-tab-validation field-group-tabs-validation"
>
A11y enhanced:
<input
data-drupal-selector="edit-field-office-hours-office-hours-0-value-12-starthours-time"
type="time"
step="60"
data-help="Time in format hh:mm"
id="edit-field-office-hours-office-hours-0-value-12-starthours-time"
name="field_office_hours[office_hours][0][value][12][starthours][time]"
class="form-time form-element form-element--type-time form-element--api-date"
data-once="field-group-tab-validation field-group-tabs-validation"
>
The title attribute is read out but does not enhance the user experience (on the contrary, by being too verbose).
I was not sure where data-help is used, maybe just leave it untouched. But the hint including seconds seems wrong to me.
Especially keep text designed for screen readers as short as possible because every field itself delivers extra text on top. Interested in trying yourself? Our community friends at the Company for the Development of Things have a list of free screen readers for all OS.
Advanced
The action links should better be transformed into buttons. If each gets a dedicated class they can even be visually reduced to icons (something like "plus, trash + clone"). The button action should result in feedback/announcements like e. g. "Values removed."
I see that this may conflict with the patch in Replace operation links in the widget with a dropbutton. It should be possible to change that to work with buttons, too (see Paragraphs's Stable widget, Add mode "Dropdown button").
Remaining tasks
Write patches.
Discuss this with contributors over in the related issue.
| Comment | File | Size | Author |
|---|---|---|---|
| #15 | office_hours-3476793_14-remainder.patch | 8.44 KB | johnv |
Issue fork office_hours-3476793
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
hexabinaerComment #3
hexabinaerComment #4
tobiasbComment #5
tobiasbFor the record:
* size comes core datetime element, should only be added, when type is text
* same for placeholder
* funny, but clever
data-helpcomes from core just for IE11 https://www.drupal.org/node/3081864(Todo find/create core issue)
Comment #6
hexabinaerOh, I wasn't aware of that. Thanks for the research!
Comment #7
tobiasbComment #9
johnvThanks for all your effort.
Some questions about the MR:
-1,7 : why remove the function name?
-95,12, 126,9: why check for slot, nextSlot, if thisis not done in the upper lines, and also not in 198 (copy)?
-198, -218: plese explain why 'data-drupal-selector$' is replaced by 'data-action' ? (mind the wild card) , since thisis introduced only recently.
-198: $(this).parents('.dropbutton-wrapper') : I guess you tested with the dropbutton issue implemented?
in OfficeHoursBaseSlot , you replace the links with 'button'. Not sure from the comments above, is this preferable to the dropbutton? Is thisin line with the drupal core standard behaviour?
Also, why introduce sprintf? Can we keep the array declaration?
Comment #10
johnvJust for future reference, please add inline comments like we did in the past: "// Add a label/header/title for accessibility (a11y) screen readers."
Comment #11
hexabinaer@johnv thanks for taking the time to look into the diff and for the detailed feedback!
This is one of the major improvements for screen reader users: buttons trigger actions/behaviour whereas links should take you to a new page. It's about semantics, not about what the element looks like. That said, a dropbutton ist just a wrapper (that must be accessible, too, of course) to save space in complex UIs. We know the concept from Views (legitimately wrapping operations links as well as from the optional Paragraphs dropbutton widget (wrapping buttons).
It is an ongoing process to replace inappropriate elements, in core as well as in contrib.
As to the other questions, ping @tobiasb
Comment #12
tobiasb@johnv It is better to write your questions in the MR.
* IIFEs does not need a function name. example: https://git.drupalcode.org/project/drupal/-/blob/11.x/core/misc/ajax.js?...
* The check for slot is gone
* I reuse the pattern data-drupal-selector again
Drupal core does not support native buttons via form api, therefore we hardcode the buttons. But I added a todo with a link to #1671190: Use <button /> form element type instead of <input type="submit" />.
Comment #13
hexabinaer@johnv re.
Not exactly but we took the understandable user story into account. Buttons would of course take up even more space than the links. tobiasb took another turn on the code, added comments (he says sorry for adding in late) and did some refactoring.
A follow-up idea: Allow site-builders to decide whether they want to wrap the options in a dropbutton or not (setting in form display).
Further answers to your questions (or new ones): let's use code comment threads to make sure we're still referencing to the same lines of code.
Comment #15
johnvAbove patch adds the Announcement and some coding standards.
I also added
'#wrapper_attributes' => ['header']to Week and List, next to ExceptionsThe attached file contains the remainder of the patch. Sorry for not using fancy tools.
For the time element, need to check that separately - perhaps in a separate ticket?
For the dropbutton, I'd like to combine with aforementioned #3135259: Replace operation links in the widget with a dropbutton. I will update that ticket.
For "Action links have an empty href attribute, no aria attributes", I see no other way atm?
Comment #16
hexabinaerLooking into it soon.
Just to let you know, I noticed one more: The season titles should rather be rendered in
<caption>markup. Replacing the weekday table header cell with it might be confusing (arguably). It would be helpful for theming, too because season names might consume more space that the weekdays (especially when using 2ch or 3ch abbreviations).I'll get back to that.
Comment #17
johnv@hexabinaer, at least in the 'table' formatter, to me it seems the season title is already in the caption.
[Edit] Oh, i see that it is located only above the first column, not spanning all columns. The other column headers/captions are not-visible.
Comment #18
johnvLet's reopen this issue, or open a new one, when we find something to improve.
Comment #20
hexabinaerGetting back to the table caption topic (context above still useful): Let's try and make screens readers only read out as much as necessary. The difference is: table headers (th, all dimensions) are being read out before the data cell in question. That makes sense for large data tables. Table captions are only read once, just like their headline character suggests.
Recommended WAI tutorial (very quick read)
Actually the horizontal table thead (currently containing "Day" and "time slot") is not even necessary here because it does not deliver essential information. Whereas the header cells in the first column do (that's why we patched that).
Ideally, an office hours table would be read like this:
"Regular office hours. Monday to Friday - 8 a.m. to 5 p.m. Saturday - 9 a.m. to 3 p.m. Sunday - closed all day."
And a season: "Winter season. Monday to Friday - 9 a.m. to 4 p.m. ..."
That's why I would opt for
<caption>as the tag for the season name and for consistency, for an additional "Regular hours" label as well.Comment #21
johnvComment #22
johnvI am open for a contributed patch.
Comment #23
johnvPlease check latest version. There was a typo, which is now fixed.