Skip to content

Commit 8546297

Browse files
committed
fix(material/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 71b7b15 commit 8546297

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
@@ -1081,18 +1081,32 @@ describe('MatDialog', () => {
10811081
beforeEach(() => document.body.appendChild(overlayContainerElement));
10821082
afterEach(() => document.body.removeChild(overlayContainerElement));
10831083

1084-
it('should focus the first tabbable element of the dialog on open', fakeAsync(() => {
1084+
it('should focus the dialog container by default', fakeAsync(() => {
10851085
dialog.open(PizzaMsg, {
1086-
viewContainerRef: testViewContainerRef
1086+
viewContainerRef: testViewContainerRef,
10871087
});
10881088

10891089
viewContainerFixture.detectChanges();
10901090
flushMicrotasks();
10911091

10921092
expect(document.activeElement!.tagName)
1093-
.toBe('INPUT', 'Expected first tabbable element (input) in the dialog to be focused.');
1093+
.toBe('MAT-DIALOG-CONTAINER', 'Expected dialog container to be focused.');
10941094
}));
10951095

1096+
it('should focus the first tabbable element of the dialog on open when autoFocus is enabled',
1097+
fakeAsync(() => {
1098+
dialog.open(PizzaMsg, {
1099+
viewContainerRef: testViewContainerRef,
1100+
autoFocus: true
1101+
});
1102+
1103+
viewContainerFixture.detectChanges();
1104+
flushMicrotasks();
1105+
1106+
expect(document.activeElement!.tagName)
1107+
.toBe('INPUT', 'Expected first tabbable element (input) in the dialog to be focused.');
1108+
}));
1109+
10961110
it('should allow disabling focus of the first tabbable element', fakeAsync(() => {
10971111
dialog.open(PizzaMsg, {
10981112
viewContainerRef: testViewContainerRef,

0 commit comments

Comments
 (0)