diff --git a/examples/combobox/combobox-select-only.html b/examples/combobox/combobox-select-only.html
index 83ca76e4ca..a17c97d229 100644
--- a/examples/combobox/combobox-select-only.html
+++ b/examples/combobox/combobox-select-only.html
@@ -83,6 +83,7 @@
Accessibility Features
The value is set when users press Space, Enter, or Tab, or when focus moves out of the combobox.
The current value is retained if the listbox is closed with Escape or if the user collapses the list by clicking the input.
+ Browsers do not manage visibility of elements referenced by aria-activedescendant
like they do for elements with focus. When a keyboard event changes the active option in the listbox, the JavaScript scrolls the option referenced by aria-activedescendant
into view. Managing aria-activedescendant
visibility is essential to accessibility for people who use a browser's zoom feature to increase the size of content.
diff --git a/examples/combobox/js/select-only.js b/examples/combobox/js/select-only.js
index f8441cfc51..fdf5874a81 100644
--- a/examples/combobox/js/select-only.js
+++ b/examples/combobox/js/select-only.js
@@ -128,6 +128,20 @@ function getUpdatedIndex(currentIndex, maxIndex, action) {
}
}
+// check if element is visible in browser view port
+function isElementInView(element) {
+ var bounding = element.getBoundingClientRect();
+
+ return (
+ bounding.top >= 0 &&
+ bounding.left >= 0 &&
+ bounding.bottom <=
+ (window.innerHeight || document.documentElement.clientHeight) &&
+ bounding.right <=
+ (window.innerWidth || document.documentElement.clientWidth)
+ );
+}
+
// check if an element is currently scrollable
function isScrollable(element) {
return element && element.clientHeight < element.scrollHeight;
@@ -318,6 +332,12 @@ Select.prototype.onOptionChange = function (index) {
if (isScrollable(this.listboxEl)) {
maintainScrollVisibility(options[index], this.listboxEl);
}
+
+ // ensure the new option is visible on screen
+ // ensure the new option is in view
+ if (!isElementInView(options[index])) {
+ options[index].scrollIntoView({ behavior: 'smooth', block: 'nearest' });
+ }
};
Select.prototype.onOptionClick = function (index) {
@@ -364,6 +384,10 @@ Select.prototype.updateMenuState = function (open, callFocus = true) {
const activeID = open ? `${this.idBase}-${this.activeIndex}` : '';
this.comboEl.setAttribute('aria-activedescendant', activeID);
+ if (activeID === '' && !isElementInView(this.comboEl)) {
+ this.comboEl.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
+ }
+
// move focus back to the combobox, if needed
callFocus && this.comboEl.focus();
};