Updated as of #37.
The relevant component should probably be datetime_range.module, but that's not an option.
Problem/Motivation
In a datetime range field, the visually-hidden labels for the "Start" and "End" sets of inputs are indistinguishable in some browser / screenreader combinations.
For the "Date and time" variant, the respective inputs are simply labeled:
- Date
- Time
- Date
- Time
The context from the visible texts "Start date" and "End date" are not included in the accessible names of the corresponding inputs.
Therefore, in browsers that do not provide a field summary like Safari, there is no context to distinguish the "Start date" field from the "End date" field, and the "Start time" field from the "End time" field.
This is apparent in VoiceOver with FireFox and Edge, and is demonstrated in Edge by the video in #37.
Steps to reproduce
- Enable the
datetime_rangemodule. - Go to
/admin/structure/typesand add a datetime range field to a content type. On a new installation without content types, you can quickly add an article content type withdrush recipe core/tests/fixtures/recipes/article_content_type. - In Firefox or Edge, go to
/node/add/content-type. Example:/node/create/article. - Enable a screen reader and observe the announced names from the date & time components of the datetime range field.
Expected behavior
The the announced input names are easily distinguishable.
Actual behavior
They're not easily distinguishable.
Proposed resolution
For the "Date and time" variant, change the respective field labels from:
- Date
- Time
- Date
- Time
to:
- Start date
- Start time
- End date
- End time
Also make similar changes for these other variants of the datetime range field type
- "Date only"
- "All day"
This should not require template changes.
Example markup change
Note: This markup is from the Stark theme. The output from other themes may be slightly different, and the element attributes will vary with the name provided when creating the field. The important parts are the changes to the text inside the label elements.
Current
<fieldset data-drupal-selector="edit-field-datetime-range-field-0" id="edit-field-datetime-range-field-0"
class="js-form-item form-item js-form-wrapper form-wrapper">
<legend>
<span class="fieldset-legend">Datetime range field</span>
</legend>
<div class="fieldset-wrapper">
<h4>Start date</h4>
<div id="edit-field-datetime-range-field-0-value">
<div
class="js-form-item form-item form-type-date js-form-type-date form-item-field-datetime-range-field-0-value-date js-form-item-field-datetime-range-field-0-value-date form-no-label">
<label for="edit-field-datetime-range-field-0-value-date" class="visually-hidden">Date</label>
<input data-drupal-selector="edit-field-datetime-range-field-0-value-date" type="date"
id="edit-field-datetime-range-field-0-value-date" name="field_datetime_range_field[0][value][date]" value=""
size="12" class="form-date">
</div>
<div
class="js-form-item form-item form-type-date js-form-type-date form-item-field-datetime-range-field-0-value-time js-form-item-field-datetime-range-field-0-value-time form-no-label">
<label for="edit-field-datetime-range-field-0-value-time" class="visually-hidden">Time</label>
<input data-drupal-selector="edit-field-datetime-range-field-0-value-time" type="time" step="1"
id="edit-field-datetime-range-field-0-value-time" name="field_datetime_range_field[0][value][time]" value=""
size="12" class="form-time">
</div>
</div>
<h4>End date</h4>
<div id="edit-field-datetime-range-field-0-end-value">
<div
class="js-form-item form-item form-type-date js-form-type-date form-item-field-datetime-range-field-0-end-value-date js-form-item-field-datetime-range-field-0-end-value-date form-no-label">
<label for="edit-field-datetime-range-field-0-end-value-date" class="visually-hidden">Date</label>
<input data-drupal-selector="edit-field-datetime-range-field-0-end-value-date" type="date"
id="edit-field-datetime-range-field-0-end-value-date" name="field_datetime_range_field[0][end_value][date]"
value="" size="12" class="form-date">
</div>
<div
class="js-form-item form-item form-type-date js-form-type-date form-item-field-datetime-range-field-0-end-value-time js-form-item-field-datetime-range-field-0-end-value-time form-no-label">
<label for="edit-field-datetime-range-field-0-end-value-time" class="visually-hidden">Time</label>
<input data-drupal-selector="edit-field-datetime-range-field-0-end-value-time" type="time" step="1"
id="edit-field-datetime-range-field-0-end-value-time" name="field_datetime_range_field[0][end_value][time]"
value="" size="12" class="form-time">
</div>
</div>
</div>
</fieldset>
New
<fieldset data-drupal-selector="edit-field-datetime-range-field-0" id="edit-field-datetime-range-field-0"
class="js-form-item form-item js-form-wrapper form-wrapper">
<legend>
<span class="fieldset-legend">Datetime range field</span>
</legend>
<div class="fieldset-wrapper">
<h4>Start date</h4>
<div id="edit-field-datetime-range-field-0-value">
<div
class="js-form-item form-item form-type-date js-form-type-date form-item-field-datetime-range-field-0-value-date js-form-item-field-datetime-range-field-0-value-date form-no-label">
<label for="edit-field-datetime-range-field-0-value-date" class="visually-hidden">Start date</label>
<input data-drupal-selector="edit-field-datetime-range-field-0-value-date" type="date"
id="edit-field-datetime-range-field-0-value-date" name="field_datetime_range_field[0][value][date]" value=""
size="12" class="form-date">
</div>
<div
class="js-form-item form-item form-type-date js-form-type-date form-item-field-datetime-range-field-0-value-time js-form-item-field-datetime-range-field-0-value-time form-no-label">
<label for="edit-field-datetime-range-field-0-value-time" class="visually-hidden">Start time</label>
<input data-drupal-selector="edit-field-datetime-range-field-0-value-time" type="time" step="1"
id="edit-field-datetime-range-field-0-value-time" name="field_datetime_range_field[0][value][time]" value=""
size="12" class="form-time">
</div>
</div>
<h4>End date</h4>
<div id="edit-field-datetime-range-field-0-end-value">
<div
class="js-form-item form-item form-type-date js-form-type-date form-item-field-datetime-range-field-0-end-value-date js-form-item-field-datetime-range-field-0-end-value-date form-no-label">
<label for="edit-field-datetime-range-field-0-end-value-date" class="visually-hidden">End date</label>
<input data-drupal-selector="edit-field-datetime-range-field-0-end-value-date" type="date"
id="edit-field-datetime-range-field-0-end-value-date" name="field_datetime_range_field[0][end_value][date]"
value="" size="12" class="form-date">
</div>
<div
class="js-form-item form-item form-type-date js-form-type-date form-item-field-datetime-range-field-0-end-value-time js-form-item-field-datetime-range-field-0-end-value-time form-no-label">
<label for="edit-field-datetime-range-field-0-end-value-time" class="visually-hidden">End time</label>
<input data-drupal-selector="edit-field-datetime-range-field-0-end-value-time" type="time" step="1"
id="edit-field-datetime-range-field-0-end-value-time" name="field_datetime_range_field[0][end_value][time]"
value="" size="12" class="form-time">
</div>
</div>
</div>
</fieldset>
Remaining tasks
- Make the changes.
- Update or add tests.
User interface changes
Visually, no changes.
Screen reader users will perceive the new names for the corresponding inputs.
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #43 | safari.mp4 | 1.44 MB | rkoller |
| #43 | edge.mp4 | 1.19 MB | rkoller |
| #43 | firefox.mp4 | 1.38 MB | rkoller |
| #37 | 2896683-37-edge-voiceover-with-form-controls-rotor-menu.mp4 | 1.19 MB | kentr |
| #31 | safari_date_entry.mp4 | 2.01 MB | rkoller |
Issue fork drupal-2896683
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
mpdonadioWorth mentioning that in HTML5 browsers there is usually some indication on what goes in there. This is Chrome on OSX:
We also have invisible labels on each input element.
There is a related issue about the input format help text (it's on the timestamp widget), but I can't find it right now.
Comment #4
ifrikComment #5
andrewmacpherson commentedAs a bug report this is eligible for 8.4.x releases.
Comment #6
BarisW commentedComment #7
BarisW commentedWould it work if we just add a placeholder in the form 'dd-mm-yyyy' and '--:--:--' to these form elements? This would add a fallback for browser who don't add a placeholder themselves.
We could do this in
processDatetime, where thetitleis set as well:However, the
formatExamplecallback returns an example in the form 'Date (e.g. 2017-09-29)', so we might want to add an extra helper function likeformatExample(formatPlaceholder?) that will return 'yyyy-mm-dd' based on 'Y-m-d'?Comment #8
mgiffordPlaceholder are often a problem for both blind and low vision users. Plus, once you click on them they go away. Having a description (visible or not) that is semantically linked with the label with something like aria-describedby would be best.
Comment #15
larowlanIs this still an issue?
Comment #17
jaime@gingerrobot.com commentedComment #18
jaime@gingerrobot.com commentedHi larowlan, Yes this is my fresh install of drupal 10 dev.
I've added tags to this to make sure it's grouped together for the #Usability team to decide what should be done. [2897397]
Comment #19
jaime@gingerrobot.com commentedComment #20
jaime@gingerrobot.com commentedComment #24
xjmComment #25
somatick commentedAs it is presently there is a visually hidden label for both the date and time fields, and the inputs themselves use the correct html input types to allow the browser to handle the rendering of the individual field types natively. So I'd say it's less of an issue than it was, although whether that meets accessibility and usability targets would require input from those stakeholders
Comment #26
jeantttttt commentedNote:
The Datetime range field can be added in Drupal 11 core via the Datetime Range module. Ensure that this has been enabled from ‘Extend’. Add a Date and Time field, then select ‘Date range’
The issue appears to be visually fixed as of Drupal 11, with placeholder values placed within the date and time fields. Both prefilled placeholder values and help text are customisable via 'Manage Fields'.
However, accessibility testing is still required to ensure that relevant fields can easily read by assistive software.
Solution by @jeantttttt and @r.imassi
Helped by @xjm and @quietone
Comment #27
xjmThanks @jeantttttt and @r.imassi!
Based on #25 and #26, I think we can rescope this issue to just do accessibility testing to ensure the hidden labels in #25 are sufficient for screen reader and similar usecases.
If it passes accessibility testing, this issue can be marked "Closed (duplicate)" (if we happen to find the issue that originally improved this) or "Closed (outdated)" otherwise.
If it's not sufficiently accessible, then we should rescope this to be about adding the needed ARIA functionality.
Tagging for accessibility review of the current state in HEAD.
Comment #28
smustgrave commentedUsing the ANDI toolbar tool I can confirm it does have a label. Will ping the accessibility guys
Comment #29
kentr commentedtl;dr: Research in progress.
I just checked on
mainin Edge with VoiceOver. My observation is that the fields do have accessible names, as mentioned in #28.However, it's not apparent whether the fields are the "Start Date" and "Start Time" as opposed to the "End Date" and "End Time".
So, my first impression is that now there is a different bug. Attached video shows this behavior.
The text "Start date" and "End date" are inside
h4elements, which creates another problem that may be contributing to this (the text isn't automatically included into the field names). That particular issue is probably covered by #3587677: heading-order: Ensure the order of headings is semantically correct, b/c my guess is that they all usedatetime-wrapper.html.twig.Comment #30
smustgrave commentedSeem what we could do here is change to start and end time?
Comment #31
rkollerre: @kentr voiceover announces in the the summary for the date range field that the date range field first has the date and time for the start date and then the date and time for the end date. but within the date time field steppers you not necessarily have the situational awareness in the aural interface if you are in the fields for the start or end time.
in general it has to be noted that browsers improved the support for the date and time fields significantly since 2017 when this issue was created. so the status quo is quite good.
in regard to the point @kentr raised in #29 i'Ve quickly recorded three short videos to illustrate that each browser employs a different value for an empty field. Chrome based browsers, edge in my case. use odd values (edge.mp4), while firefox uses "NaN" (firefox.mp4), and safari uses just "0" (safari.mp4).
It has to be noted that the color contrast the placeholder text uses in firefox and edge has a high enough contrast, but in safari the contrast is too light (i just used a color picker and i get ~2.13:1 for #b0b1bb against #ffffff - ideally the contrast should be at least 4.5:1).
Then there are two mostly ux related problems.
You know that the date and time field are required, it gets properly announced and communicated. The only problem is it is not clear if you have to enter values to the second. Personally, by reflex, i tend to only enter hours and minutes, and then assume that the value provided by the placeholder is being used without any entry. so entering 12:12 as the start time i would expect that 12:12:00 PM is being used based on the default placeholder values, but as you can see and hear the validation fails (safari_date_entry.mp4 - the video also illustrates the entire interaction with the date range field in safari and voice over, but i suppose that detail is out of the scope for this issue)
the other detail is in regard of labeling, by accident we've discussed the following issue #3023777: datetime_range fields have confusing options for date type setting during the last ux meeting on friday. on the field settings page for the date range field you have the options "All day" and "Date only" aside "daten and time"- on the node edit form the user has no way to distinguish if the field at hand is a "all day" field or "date only" field. it might be good if the editor entering knows which option was used and in consequence also knows what the difference between those to options actually is.
p.s. there is one detail i wanted to test but i am blanking where to change that setting, or at this point i am even uncertain if it is possible at all. is it possible to change the timeformat that is used on node edit forms? at the moment the entry into the date range field is in the 12h format. but you are only able to choose a time format on the "manage display" page for the field, but not on "manage form display".
Comment #33
vishal choudharyI reviewed the Date and Time label behavior, and the same implementation exists in previous Drupal versions, including 8.x, 9.x, and 10.x.
No need to added the label text on the Time field.
The issue appears to be visually resolved in Drupal 11, as placeholder values are now displayed inside the date and time fields.
Therefore, we updated the field label to “Date + Time” from the Manage Fields configuration for better clarity.
Attached screenshot for reference.
Comment #34
smustgrave commentedThat wasn't really what this issue was referring to and kinda bypassed all that was discussed before.
@rkoller thanks for the write up, some of those seem like their own issue but would you say though that it's properly labeled?
Comment #35
rkollerre #34: first in regard to the question if the date and time fields are properly labeled.
Sighted users are provided with the general context (start date and end date) by the field labels, while the details are conveyed via the placeholder text. Problem here, the information communicated via the placeholder text might be not accessible for everyone in every situation due to the lack of color contrast. Therefore people with visual impairments might run into barriers same as people without any visual impairment under certain conditions like bright day light.
Another detail to denote in the context of labeling that I've just noticed while writing up this summary. The iconography on the date and time fields shown in the "user interface changes" section in the issue summary doesn't apply to every browser. For Blink based browsers date and time fields have an icon but they have no AM/PM stepper, for Gecko based browsers date fields have an icon while time fields have no icon and they have a AM/PM stepper, while Webkit based browsers have no icons at all on date nor time field, but they have a AM/PM stepper. And it has to be noted that the Iconography provides visual cues only to sighted users.
Screenreader users might have problems depending on the browser they are using, a detail @kentR reminded me to. In Safari, when you tab through a form, and you get to the date field for the start date of a datetime range you get an announcement with a summary of the entire range, the steps itself are provided without any context afterwards (see safari_date_entry.mp4). In Firefox and Edge that summary is entirely missing, you only have the steps without any context when you tab through the form.
I've discussed the scope for this issue and which of the raised points should be moved to followups with @kentr via Slack - we've agreed on the following suggestion:
The only problem that should be fixed within the scope of this issue is a detail @kentr came up with. Currently the label on the stepper is
but it would be possible to change the visually-hidden label to
That way it would be ensured that the context is conveyed in the aural interface for every step. The rest of the following points should be moved to dedicated followup issues from our point of view:
Comment #36
mgiffordThanks @rkoller this looks good. Would be nice to resolve this issue.
This seems like a good approach.
Comment #37
kentr commentedThanks @rkoller for posting the discussion summary.
Removing Needs accessibility review based on input from the accessibility folks.
Updated the IS and attached a more complete video with sound of VoiceOver in Edge while moving through the Form controls rotor menu with the arrow key.
Comment #38
kentr commentedComment #39
kentr commentedComment #40
smustgrave commentedComment #42
smustgrave commentedReady for some thoughts
Comment #43
rkollerthank you for working on this! ive quickly checked out MR15802... ive tested on macos with latest safari, firefox, and edge in combination with voiceover.
sounds like only in edge the visually hidden labels are announced for every step (edge.mp4). in firefox (firefox.mp4) and safari (safari.mp4) that labeling for the steppers is not announced. and only in safari you have that summary at the beginning when the focus steps into the date range field and onto the start date field. neither edge nor firefox do have that kind of summary. and it has also be noted that the datefields behave differently interaction wise across browsers in regard to keyboard interaction. in particular edge stands out since only the first stepper is within the tab order the other steps have to be reached via the arrow key, an behavior unavailable for safari and chrome.
and seeing and hearing the differing behavior in between browsers with voiceover, i think it would be necessary to also test in more screenreaders aside voiceover. there might be more "surprises"
Comment #44
kentr commentedLooks like the proposed resolution didn't work as expected.
Putting at Needs work just to save other people from reviewing further until we figure out what's next.
Comment #45
kentr commentedI also had the thought of replacing the two
h4elements with twofieldsetelements.Seems like that would especially make sense to me when there is both a date and a time field, because
fieldsetis meant to group multiple controls. Not sure how it would be when there is only one field in each.This would probably require template changes, though. It might also require CSS changes, because the nested fieldsets might not look great.
Comment #46
kentr commentedAnother thing that came up in a discussion with @rkoller is that Adrian Roselli prefers plain text fields for known dates and says
<input type="date">is a problem for voice users.Adrian also references this Graham Armfield post which says:
The Graham Armfield post is from 2019, so some of it may be out of date. Also, some of his points are related to HTML5 validation.
I later found out that the GOV.UK Design System also prefers text fields for memorable / known dates.
I'm mentioning this because I'm not convinced that all of the other problems that @rkoller found with these native fields are solvable, such as the color contrast of the placeholder text and the order of the day & month components based on locale.
So, I'm wondering if the fix for this issue lies in replacing these native date & time fields with something more accessible, starting by offering an option of multiple plain text fields for the cases where a date picker isn't required.
@rkoller said he would inquire with the UX people whether there are also general UX problems with these native fields (separate from the accessibility issues).