-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scroll to label or legend when linked from error summary #1056
Conversation
2ad6d99
to
93d4a9d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a change log entry, and pending testing, but this approach is a lot nicer than I thought it'd have to be!
93d4a9d
to
852f017
Compare
|
||
describe.each(inputTypes)('when linking to %s', async (_, inputId, legendOrLabelSelector) => { | ||
beforeAll(async () => { | ||
await page.goto(`${baseUrl}/examples/error-summary`, { waitUntil: 'load' }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not super-keen on hooking into the review app's examples, but couldn't think of a better way of doing this at the minute. This is something I'd definitely to revisit in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is an issue with all our examples like this.
IE11 + Jaws announces for example: |
852f017
to
4c4e8a5
Compare
4c4e8a5
to
af475d6
Compare
There is still 'jumpy' scrolling in IE8 and IE9, where clicking the link takes you first to the input and then very quickly 'back up' to the legend or label: However, I've been able to fix this in IE10 and above 🎉 Whilst it's not ideal, I think it is acceptable for IE8 and IE9 to do this. Alternatively, we could choose to do nothing in browsers that don't support history.pushState, which would mean in IE8 and IE9 you'd end up jumping to the input with the legend or label off the top of the screen. |
// in Edge 17). | ||
if (window.history.pushState) { | ||
window.history.pushState(null, null, '#' + inputId) | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One alternative might be to avoid setting a hash at all, I'm not sure what the user need is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH, it's just maintaining the existing behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NickColley Using the hash means you can press "back" and be jumped up to the top of the page again. This is the current behaviour, I've seen people do this—it's pretty useful.
@36degrees For older browsers, could you use a timeout to allow scrollIntoView() to complete before changing the hash? It likely won't scroll again as the input is already in view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@colinrotherham good call, but unfortunately changing the hash does cause IE8 and IE9 to scroll the target input to the top of the viewport, even if it is already in the viewport.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boo shame! Nevermind. I've tried your branch locally and the jump is acceptable, the GIF makes it look worse than it is.
It looks like this change also improves things for NVDA users: Text InputBefore: "Edit, has autocomplete" TextareaBefore: "Edit, multiline" SelectBefore: "Combobox, collapsed, option one." SelectBefore: "Spin button, edit" File UploadBefore: "Browse, no file selected" RadiosBefore: "Radio button, not checked" CheckboxesBefore: "Checkbox, not checked" Single checkboxBefore: "Checkbox, not checked" |
By default, the browser will scroll the target into view. Because our labels or legends appear above the input, this means the user will be presented with an input without any context, as the label or legend will be off the top of the screen. Manually handling the click event, focussing the element and scrolling the question into view solves this. This also results in the label and/or legend being announced correctly in NVDA (as tested in 2018.3.2) - without this only the field type is announced. For example: For a Text Input: Before: "Edit, has autocomplete" After: "Label for input, edit, has autocomplete, problem with input, blank" For a Textarea: Before: "Edit, multiline" After: "Label for textarea, edit, multiline, problem with input, blank" For a Select: Before: "Combobox, collapsed, option one." After: "Label for select, Combobox, option one, collapsed, problem with select" For a Select: Before: "Spin button, edit" After: "Label for date input, grouping, problem with date input. Day, spin button, edit, blank" For a File Upload: Before: "Browse, no file selected" After: "Browse, button" For a Radios: Before: "Radio button, not checked" After: "Legend for radios, grouping, problem with radios. Label for first radio button, radio button not checked, 1 of 2" For a Checkboxes: Before: "Checkbox, not checked" After: "Legend for checkboxes, grouping. Label for first checkbox, checkbox not checked." For a Single checkbox: Before: "Checkbox, not checked" After: "Label for single checkbox, checkbox not checked, problem with single checkbox"
Make it clearer when testing with assistive technologies exactly what is being read out.
c7a1aa9
to
44c6e2c
Compare
I'm happy that this is good to review now 👍 |
This introduces guidance to help service teams link from the error summary to the corresponding questions in an accessible way. Our approach mirrors the recommended approach from WebAIM [1], linking to the input in all cases. This does mean that the input would natively be focussed at the top of the viewport, which means the associated label or legend would not be visible to the user. There is a corresponding change to Frontend [2] to manually manage the focus and scroll state, allowing us to target and focus the input whilst scrolling to the label or legend. To understand how to do this in an accessible way, we carried out research using a simplified test case [3] and the assistive technologies we aim to support: ## Voiceover + Safari (macOS El Capitan) The behaviour differs depending on whether you use Enter or Ctrl-Opt-Space to navigate. When navigating using Enter: - linking to the label or legend generally resulted in the focus moving but nothing being announced. - linking to the input generally worked well, but the error message (associated using aria-describedby) was not announced for radios or checkboxes. When navigating using Ctrl-Opt-Space: - linking to a label worked but it was not clear how to interact with the related form contrl (the label would be read followed by "You are currently on a text element, inside of web content. To exit this web area, press Ctrl-Option-Shift-Up Arrow.") - linking to the input worked OK, but the associated legend and error message were not read out for inputs within a fieldset Overall, linking to the input worked better. ## Voiceover + Safari (iOS 11) There doesn't seem to be any way to get Voiceover on iOS to do anything useful, regardless of where you link to. For everything except selects and file inputs (!?) linking to the input results in the focus and VO cursor moving, but nothing being announced. Linking to the label or legend caused Voiceover to repeat itself, and neither the focus nor the VO cursor moved at all. There is no good option. ¯\_(ツ)_/¯ ## TalkBack + Google Chrome (Android) Linking to the input worked OK, but the associated legend and error message were not read out for inputs within a fieldset. Linking to labels resulted in the page scrolling but nothing being announced. Linking to legends resulted in the legend and error message being read, but with no clear way to navigate to the corresponding control. Overall, linking to the input worked better. ## NVDA + Firefox Linking to the input only described the input type, without reading any of the associated context (label, legend, error message). Linking to the label resulted in the label being read out, preceded by 'clickable'. Overall, linking to the label worked better. However, the manual focus state management introduced in alphagov/govuk-frontend#1056 means that linking to the input now works really well, announcing all expected context. ## JAWS2018 + IE11 Linking to the label resulted in the focus shifting down but then immediately returning to the top of the page and enters reading mode. Linking to the input generally worked well, but the error message was not read in some cases (text areas, and error messages associated with fieldsets) Overall, linking to the input worked better. ## Dragon NaturallySpeaking Clicking links using Naturally Speaking's commands worked as expected in all cases. [1]: https://webaim.org/techniques/formvalidation/ [2]: alphagov/govuk-frontend#1056 [3]: https://36degrees.github.io/linking-to-form-inputs/
Glad to see this get done, the NVDA improvements are awesome. |
Needs a changelog entry |
Bugs filed as a result of this work:
|
Linking to this ticket alphagov/govuk-design-system-backlog#155 so it can be documented how the error summary links to each form control by ID (not a legend/label). I've found a mix of behaviours across our services (some linking to empty links |
@colinrotherham there's a PR open on the Design System which adds guidance around this to the Error Summary – if you fancy checking it out, it'd be great to get feedback from someone outside the team. |
By default, the browser will scroll the target into view. Because our labels or legends appear above the input, this means the user will be presented with an input without any context, as the label or legend will be off the top of the screen.
Manually handling the click event, focussing the element and scrolling the question into view solves this.
To do
Test in all supported browsers
Test in assistive technologies
https://trello.com/c/s9wGbLZW/1454-scroll-to-show-the-label-or-legend-when-linking-from-the-error-summary