Skip to content

Commit 931c220

Browse files
authored
SelectBox: Use visually-hidden for describedby with VoiceOver. Fixes: microsoft#60429
1 parent 1f482cd commit 931c220

2 files changed

Lines changed: 13 additions & 9 deletions

File tree

src/vs/base/browser/ui/selectBox/selectBoxCustom.css

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,16 @@
7878
white-space: nowrap;
7979
}
8080

81-
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row > .option-text-description {
82-
display: none;
81+
/* Accepted CSS hiding technique for accessibility reader text */
82+
/* https://webaim.org/techniques/css/invisiblecontent/ */
83+
84+
.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row > .visually-hidden {
85+
position: absolute;
86+
left: -10000px;
87+
top: auto;
88+
width: 1px;
89+
height: 1px;
90+
overflow: hidden;
8391
}
8492

8593
.monaco-select-box-dropdown-container > .select-box-dropdown-container-width-control {

src/vs/base/browser/ui/selectBox/selectBoxCustom.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import 'vs/css!./selectBoxCustom';
77

8-
import * as nls from 'vs/nls';
98
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
109
import { Event, Emitter, chain } from 'vs/base/common/event';
1110
import { KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes';
@@ -50,6 +49,7 @@ class SelectListRenderer implements IRenderer<ISelectOptionItem, ISelectListTemp
5049
data.root = container;
5150
data.optionText = dom.append(container, $('.option-text'));
5251
data.optionDescriptionText = dom.append(container, $('.option-text-description'));
52+
dom.addClass(data.optionDescriptionText, 'visually-hidden');
5353

5454
return data;
5555
}
@@ -60,18 +60,14 @@ class SelectListRenderer implements IRenderer<ISelectOptionItem, ISelectListTemp
6060
const optionDisabled = (<ISelectOptionItem>element).optionDisabled;
6161

6262
data.optionText.textContent = optionText;
63-
data.root.setAttribute('aria-label', nls.localize('selectAriaOption', "{0}", optionText) + ',.');
6463

6564
if (typeof element.optionDescriptionText === 'string') {
6665
const optionDescriptionId = (optionText.replace(/ /g, '_').toLowerCase() + '_description_' + data.root.id);
67-
data.root.setAttribute('aria-describedby', optionDescriptionId);
66+
data.optionText.setAttribute('aria-describedby', optionDescriptionId);
6867
data.optionDescriptionText.id = optionDescriptionId;
69-
data.optionDescriptionText.setAttribute('aria-label', element.optionDescriptionText);
68+
data.optionDescriptionText.innerText = element.optionDescriptionText;
7069
}
7170

72-
// Workaround for list labels
73-
data.root.setAttribute('aria-selected', 'true');
74-
7571
// pseudo-select disabled option
7672
if (optionDisabled) {
7773
dom.addClass((<HTMLElement>data.root), 'option-disabled');

0 commit comments

Comments
 (0)