Skip to content

Commit

Permalink
Merge pull request #2677 from alphagov/error-summary-page-load-focus
Browse files Browse the repository at this point in the history
Amend error summary markup to fix page load focus bug in JAWS 2022
  • Loading branch information
owenatgov committed Aug 18, 2022
2 parents 1cc0a07 + 368a404 commit c31c4be
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 30 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

## Unreleased

### Recommended changes

#### Remove `aria-labelledby`, remove `id="error-summary-title"` from title and move `role="alert"` to child container on the error summary component

If you're not using the Nunjucks macros, you can improve the experience for screen reader users by making these changes to the error summary markup:

- Remove `aria-labelledby="error-summary-title"` and `role="alert"` from the parent element (`govuk-error-summary`)
- Add a `div` wrapper around the contents of `govuk-error-summary` with the attribute `role="alert"`
- Remove `id="error-summary-title"` from the error summary `h2` (`govuk-error-summary__title`)

This will enable screen reader users to have a better, more coherent experience with the error summary. Most notably it will ensure that users of JAWS 2022 or later will hear the entire contents of the error summary on page load and therefore have further context on why there is an error on the page they're on.

This was added in [pull request #2677: Amend error summary markup to fix page load focus bug in JAWS 2022](https://github.com/alphagov/govuk-frontend/pull/2677)

## 4.3.1 (Patch release)

### Recommended changes
Expand Down
44 changes: 24 additions & 20 deletions src/govuk/components/error-summary/template.njk
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
<div class="govuk-error-summary
{%- if params.classes %} {{ params.classes }}{% endif %}" aria-labelledby="error-summary-title" role="alert"
{%- if params.classes %} {{ params.classes }}{% endif %}"
{%- if params.disableAutoFocus %} data-disable-auto-focus="true"{% endif %}
{%- for attribute, value in params.attributes %} {{ attribute }}="{{ value }}"{% endfor %} data-module="govuk-error-summary">
<h2 class="govuk-error-summary__title" id="error-summary-title">
{{ params.titleHtml | safe if params.titleHtml else params.titleText }}
</h2>
<div class="govuk-error-summary__body">
{% if caller or params.descriptionHtml or params.descriptionText %}
<p>
{{ caller() if caller else (params.descriptionHtml | safe if params.descriptionHtml else params.descriptionText) }}
</p>
{% endif %}
<ul class="govuk-list govuk-error-summary__list">
{% for item in params.errorList %}
<li>
{% if item.href %}
<a href="{{ item.href }}"{% for attribute, value in item.attributes %} {{attribute}}="{{value}}"{% endfor %}>{{ item.html | safe if item.html else item.text }}</a>
{% else %}
{{ item.html | safe if item.html else item.text }}
{# Keep the role="alert" in a seperate child container to prevent a race condition between
the focusing js at the alert, resulting in information getting missed in screen reader announcements #}
<div role="alert">
<h2 class="govuk-error-summary__title">
{{ params.titleHtml | safe if params.titleHtml else params.titleText }}
</h2>
<div class="govuk-error-summary__body">
{% if caller or params.descriptionHtml or params.descriptionText %}
<p>
{{ caller() if caller else (params.descriptionHtml | safe if params.descriptionHtml else params.descriptionText) }}
</p>
{% endif %}
</li>
{% endfor %}
</ul>
<ul class="govuk-list govuk-error-summary__list">
{% for item in params.errorList %}
<li>
{% if item.href %}
<a href="{{ item.href }}"{% for attribute, value in item.attributes %} {{attribute}}="{{value}}"{% endfor %}>{{ item.html | safe if item.html else item.text }}</a>
{% else %}
{{ item.html | safe if item.html else item.text }}
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
13 changes: 3 additions & 10 deletions src/govuk/components/error-summary/template.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,11 @@ describe('Error-summary', () => {
expect(results).toHaveNoViolations()
})

it('aria-labelledby attribute matches the title id', () => {
it('has a child container with the role=alert attribute', () => {
const $ = render('error-summary', examples.default)
const ariaAttr = $('.govuk-error-summary').attr('aria-labelledby')
const childRoleAttr = $('.govuk-error-summary div:first-child').attr('role')

expect(ariaAttr).toEqual('error-summary-title')
})

it('has role=alert attribute', () => {
const $ = render('error-summary', examples.default)
const roleAttr = $('.govuk-error-summary').attr('role')

expect(roleAttr).toEqual('alert')
expect(childRoleAttr).toEqual('alert')
})

it('renders title text', () => {
Expand Down

0 comments on commit c31c4be

Please sign in to comment.