Skip to content

Create focus-returns-trigger-9au0ou.md #2022

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

Open
wants to merge 32 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6368b71
Create focus-returns-trigger-9au0ou.md
HelenBurge Jan 31, 2023
ef40a19
Update focus-returns-trigger-9au0ou.md
HelenBurge Jan 31, 2023
12d4cac
For new rule 9au0ou "Focus returns to trigger" - adding passed exampl…
dan-tripp-siteimprove Feb 17, 2023
28dc461
Update focus-returns-trigger-9au0ou.md
HelenBurge May 4, 2023
dad5892
Merge branch 'develop' into HelenBurge-patch-2
Jym77 May 25, 2023
16eb30c
Update _rules/focus-returns-trigger-9au0ou.md
HelenBurge Jun 8, 2023
83ece03
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 6, 2025
c4da79b
Merge branch 'develop' into HelenBurge-patch-2
carlosapaduarte Feb 6, 2025
302ffdc
Update spelling-ignore.yml
HelenBurge Feb 6, 2025
8f7ce2a
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 6, 2025
24f8a6a
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 6, 2025
969770f
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 6, 2025
eb1cfe4
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
a154fc3
Create focus.md
HelenBurge Feb 7, 2025
9dc8b42
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
dc189e1
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
d05143d
Delete pages/glossary/focus.md
HelenBurge Feb 7, 2025
d593f43
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
d0c1622
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
c760002
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
545599b
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
007c767
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
4709b42
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
102a0bd
Update package.json
HelenBurge Feb 7, 2025
54afb0d
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
0ab8ed8
Update package.json
HelenBurge Feb 7, 2025
9884cc5
Update focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
3f9e26b
Update _rules/focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
541961b
Update _rules/focus-returns-trigger-9au0ou.md
HelenBurge Feb 7, 2025
e8fdf97
Update focus-returns-trigger-9au0ou.md
HelenBurge May 8, 2025
94a8083
Merge branch 'develop' into HelenBurge-patch-2
daniel-montalvo Jun 17, 2025
174d5da
whitespace test commit
dan-tripp-siteimprove Jun 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions __tests__/spelling-ignore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
- TODO
- TBD
- CJK
- TBC

# Tool and library names
- axe-core
Expand Down
245 changes: 245 additions & 0 deletions _rules/focus-returns-trigger-9au0ou.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
---
id: 9au0ou
name: Focus returns to trigger
rule_type: atomic
description: |
This rule checks that when a modal closes the focus returns to the trigger that opened the modal.
accessibility_requirements:
wcag20:2.4.3: # Focus Order (A)
forConformance: true
failed: not satisfied
passed: further testing needed
inapplicable: further testing needed
wcag-technique:G59: # Placing the interactive elements in an order that follows sequences and relationships within the content
forConformance: false
failed: not satisfied
passed: further testing needed
inapplicable: further testing needed
input_aspects:
- Accessibility Tree
- DOM Tree
acknowledgments:
authors:
- Dan Tripp
- Helen Burge
---

## Applicability

This rule applies when focus is trapped within a region activated by a trigger control that is dismissible.

## Expectation

The element that triggers the target element to become visible, is still present in the screen behind the triggered content and is the same element that receives focus when the target element stops being visible.

## Background

### Assumptions

There are no assumptions.

### Accessibility Support

Some assistive technologies on known browsers still exhibit inconsistencies. Specifically, if an element is removed from the accessibility tree after being activated (e.g., a close button), and focus is moved via JavaScript to an element that is not inherently operable (e.g., a button works, but a div with tabindex="-1" may not), the assistive technology might automatically shift focus to the closest visible element, regardless of the intended JavaScript behavior.

### Bibliography

- [Understanding Success Criterion 2.4.3: Focus Order](https://www.w3.org/WAI/WCAG22/Understanding/focus-order.html)
- [G59: Placing the interactive elements in an order that follows sequences and relationships within the content](https://www.w3.org/WAI/WCAG22/Techniques/general/G59)

## Test Cases

### Passed

#### Passed Example 1

The button that is activated to display the [modal][] gets the [focus][] returned to it when the [modal][] is dismissed using the escape key or activating close, OK or cancel button in the modal.

```html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Passed Example 1</title>
<script src="/test-assets/9au0ou/aria-apg-dialog.js"></script>
<script src="/test-assets/9au0ou/aria-apg-utils.js"></script>
<link href="/test-assets/9au0ou/aria-apg-dialog.css" rel="stylesheet" />
<link href="/test-assets/9au0ou/9au0ou.css" rel="stylesheet" />
</head>
<body>
<button type="button">Do nothing</button>
<button type="button" onclick="openDialog('dialog1', this)">Open modal dialog</button>
<button type="button">Do nothing</button>
<div id="dialog_layer" class="dialogs">
<div role="dialog" id="dialog1" aria-labelledby="dialog1_label" aria-modal="true"
class="hidden">
<h2 id="dialog1_label" class="dialog_label">Dialog title</h2>
<div class="dialog_form">Dialog content.</div>
<button type="button" class="close-button topright" aria-label="Close" title="Close"
onclick="closeDialog(this)">
&times;
</button>
<div style="text-align: right;">
<button type="button" onclick="closeDialog(this)"></button>
<button type="button" onclick="closeDialog(this)">Cancel</button>
</div>
</div>
</div>
</body>
</html>
```

#### Passed Example 2

The link that is activated to display the [modal][] gets the [focus][] returned to it when the [modal][] is dismissed using the escape key or activating close, OK or cancel button in the modal.

```html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Passed Example 2</title>
<script src="/test-assets/9au0ou/aria-apg-dialog.js"></script>
<script src="/test-assets/9au0ou/aria-apg-utils.js"></script>
<link href="/test-assets/9au0ou/aria-apg-dialog.css" rel="stylesheet" />
<link href="/test-assets/9au0ou/9au0ou.css" rel="stylesheet" />
</head>
<body>
<a href="#">Do nothing</a>
<a href="javascript:openDialog('dialog1', this)">Open modal dialog</a>
<a href="#">Do nothing</a>
<div id="dialog_layer" class="dialogs">
<div role="dialog" id="dialog1" aria-labelledby="dialog1_label" aria-modal="true"
class="hidden">
<h2 id="dialog1_label" class="dialog_label">Dialog title</h2>
<div class="dialog_form">Dialog content.</div>
<button type="button" class="close-button topright" aria-label="Close" title="Close"
onclick="closeDialog(this)">
&times;
</button>
<div style="text-align: right;">
<button type="button" onclick="closeDialog(this)">OK</button>
<button type="button" onclick="closeDialog(this)">Cancel</button>
</div>
</div>
</div>
</body>
</html>
```

### Failed

#### Failed Example 1
The button that is activated to display the [modal][] gets the [focus][] returned to the item after it when the [modal][] is dismissed.

```html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Failed Example 1</title>
<script src="test-assets/9au0ou/aria-apg-dialog.js"></script>
<script src="test-assets/9au0ou/aria-apg-utils.js"></script>
<script>

addEventListener('DOMContentLoaded', (event) => {
document.getElementById('dialog1').on_close_via_escape_key = () => {
document.getElementById('donothingbutton2').focus();
};
});

</script>
<link href="test-assets/9au0ou/aria-apg-dialog.css" rel="stylesheet">
<link href="test-assets/9au0ou/9au0ou.css" rel="stylesheet">
</head>
<body>
<button id="donothingbutton1" class="top-level-button" type="button">Do nothing</button><br><br>
<button class="top-level-button" type="button" onclick="openDialog('dialog1', this)">Open modal dialog</button><br><br>
<button id="donothingbutton2" class="top-level-button" type="button">Do nothing</button><br><br>
<div id="dialog_layer" class="dialogs">
<div role="dialog" id="dialog1" aria-labelledby="dialog1_label" aria-modal="true" class="hidden">
<div class="dialog_form">For this test: use any button, or the escape key, to close the dialog.</div>
<button type="button" class="close-button topright" aria-label="Close" title="Close" onclick="closeDialog(this); document.getElementById('donothingbutton2').focus();">
×
</button>
<div style="text-align: right;">
<button type="button" onclick="closeDialog(this); document.getElementById('donothingbutton2').focus();">OK</button>
<button type="button" onclick="closeDialog(this); document.getElementById('donothingbutton2').focus();">Cancel</button>
</div>
</div>
</div>
</body>
</html>
```

#### Failed Example 2
The button that is activated to display the [modal][] gets the [focus][] returned to the start of the page when the modal is dismissed.

```html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Failed Example 2</title>
<script src="test-assets/9au0ou/aria-apg-dialog.js"></script>
<script src="test-assets/9au0ou/aria-apg-utils.js"></script>
<script>

addEventListener('DOMContentLoaded', (event) => {
document.getElementById('dialog1').on_close_via_escape_key = () => {
document.getElementById('donothingbutton1').focus();
};
});

</script>
<link href="test-assets/9au0ou/aria-apg-dialog.css" rel="stylesheet">
<link href="test-assets/9au0ou/9au0ou.css" rel="stylesheet">
</head>
<body>
<button id="donothingbutton1" class="top-level-button" type="button">Do nothing</button><br><br>
<button class="top-level-button" type="button" onclick="openDialog('dialog1', this)">Open modal dialog</button><br><br>
<button id="donothingbutton2" class="top-level-button" type="button">Do nothing</button><br><br>
<div id="dialog_layer" class="dialogs">
<div role="dialog" id="dialog1" aria-labelledby="dialog1_label" aria-modal="true" class="hidden">
<div class="dialog_form">For this test: use any button, or the escape key, to close the dialog.</div>
<button type="button" class="close-button topright" aria-label="Close" title="Close" onclick="closeDialog(this); document.getElementById('donothingbutton1').focus();">
×
</button>
<div style="text-align: right;">
<button type="button" onclick="closeDialog(this); document.getElementById('donothingbutton1').focus();">OK</button>
<button type="button" onclick="closeDialog(this); document.getElementById('donothingbutton1').focus();">Cancel</button>
</div>
</div>
</div>
</body>
</html>
```

#### Failed Example 3
The link that is activated to display the [modal][] gets the [focus][] returned to the item after it when the [modal][] is dismissed.

```html
Code needed!
```

#### Failed Example 4
The link that is activated to display the [modal][] gets the [focus][] returned to the start of the page when the modal is dismissed.

```html
Code needed!
```

#### Failed Example 5
The page has a list of buttons that is activated to display a [modal][], the [focus][] is returned to the incorrect button on dismissing the modal.

```html
Code needed!
```

### Inapplicable

#### Inapplicable Example 1
TBC

```html
Code needed!
```

[focus]: #focused 'Definition of focused'
[modal]: https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@
{
"name": "Helen Burge",
"url": "https://github.com/HelenBurge"
},
{
"name": "Dan Tripp",
"url": "https://github.com/dan-tripp-siteimprove"
}
],
"devDependencies": {
Expand Down
21 changes: 21 additions & 0 deletions test-assets/9au0ou/9au0ou.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.close-button {
padding: 0.3rem;
margin: 0.3rem;
/*
display: inline-block;
vertical-align: middle;
overflow: hidden;
text-decoration: none;
color: inherit;
background-color: inherit;
text-align: center;
cursor: pointer;
white-space: nowrap
*/
}

.topright {
position: absolute;
right: 0;
top: 0;
}
Loading