Skip to content

Commit 5f5be59

Browse files
committed
fix(dialog): dialog content not being read out by screen readers
Currently we focus the first focusable element inside a dialog as per the accessibility recommendations, however moving focus to the first item causes some screen readers not to read out the rest of the dialog content. These changes switch to focusing the dialog container by default which allows screen readers to read out everything. If users press tab, they'll land on the first tabbable element anyways. The old behavior can still be opted into via the `autoFocus` option. Fixes #10591.
1 parent 6a7fc81 commit 5f5be59

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

src/material/dialog/dialog-config.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,11 @@ export class MatDialogConfig<D = any> {
9595
/** Aria label to assign to the dialog element */
9696
ariaLabel?: string | null = null;
9797

98+
// Note that this is disabled by default, because while the a11y recommendations are to focus
99+
// the first focusable element, doing so prevents screen readers from reading out the
100+
// rest of the dialog's content.
98101
/** Whether the dialog should focus the first focusable element on open. */
99-
autoFocus?: boolean = true;
102+
autoFocus?: boolean = false;
100103

101104
/**
102105
* Whether the dialog should restore focus to the

src/material/dialog/dialog.e2e.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ describe('dialog', () => {
5959
await element(by.id('default')).click();
6060

6161
await waitForDialog();
62-
await expectFocusOn('mat-dialog-container input');
62+
await expectFocusOn('mat-dialog-container');
6363
});
6464

6565
it('should restore focus to the element that opened the dialog', async () => {
@@ -76,7 +76,7 @@ describe('dialog', () => {
7676
await element(by.id('default')).click();
7777

7878
await waitForDialog();
79-
await pressKeys(Key.TAB, Key.TAB, Key.TAB);
79+
await pressKeys(Key.TAB, Key.TAB, Key.TAB, Key.TAB);
8080
await expectFocusOn('#close');
8181
});
8282

src/material/dialog/dialog.spec.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -981,18 +981,32 @@ describe('MatDialog', () => {
981981
beforeEach(() => document.body.appendChild(overlayContainerElement));
982982
afterEach(() => document.body.removeChild(overlayContainerElement));
983983

984-
it('should focus the first tabbable element of the dialog on open', fakeAsync(() => {
984+
it('should focus the dialog container by default', fakeAsync(() => {
985985
dialog.open(PizzaMsg, {
986-
viewContainerRef: testViewContainerRef
986+
viewContainerRef: testViewContainerRef,
987987
});
988988

989989
viewContainerFixture.detectChanges();
990990
flushMicrotasks();
991991

992992
expect(document.activeElement!.tagName)
993-
.toBe('INPUT', 'Expected first tabbable element (input) in the dialog to be focused.');
993+
.toBe('MAT-DIALOG-CONTAINER', 'Expected dialog container to be focused.');
994994
}));
995995

996+
it('should focus the first tabbable element of the dialog on open when autoFocus is enabled',
997+
fakeAsync(() => {
998+
dialog.open(PizzaMsg, {
999+
viewContainerRef: testViewContainerRef,
1000+
autoFocus: true
1001+
});
1002+
1003+
viewContainerFixture.detectChanges();
1004+
flushMicrotasks();
1005+
1006+
expect(document.activeElement!.tagName)
1007+
.toBe('INPUT', 'Expected first tabbable element (input) in the dialog to be focused.');
1008+
}));
1009+
9961010
it('should allow disabling focus of the first tabbable element', fakeAsync(() => {
9971011
dialog.open(PizzaMsg, {
9981012
viewContainerRef: testViewContainerRef,

0 commit comments

Comments
 (0)