Skip to content

Commit 1e2eacd

Browse files
authored
Merge pull request #728 from craftcms/a11y/make-code-containers-scrollable
Put overflowing containers in the focus order so they are keyboard-accessible
2 parents 3a8d52d + 925e650 commit 1e2eacd

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

docs/.vuepress/theme/layouts/Layout.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ import {
170170
getPageWithRelativePath,
171171
fixDoubleSlashes,
172172
getSameContentForVersion,
173+
makeOverflowingContainersFocusable,
173174
} from "../util";
174175
175176
import { getStorage, setStorage, unsetStorage } from "../Storage";
@@ -187,7 +188,10 @@ export default {
187188
188189
watch: {
189190
'$route.path'() {
190-
this.$refs.backToTop.focus()
191+
this.$refs.backToTop.focus();
192+
this.$nextTick(function () {
193+
makeOverflowingContainersFocusable();
194+
});
191195
}
192196
},
193197
@@ -284,6 +288,10 @@ export default {
284288
this.isSidebarOpen = false;
285289
});
286290
291+
this.$nextTick(function () {
292+
makeOverflowingContainersFocusable();
293+
});
294+
287295
// temporary means of scrolling to URL hash on load
288296
// https://github.com/vuejs/vuepress/issues/2428
289297
const hash = document.location.hash;

docs/.vuepress/theme/util/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,21 @@ function getAnchorHash(path) {
623623
return false;
624624
}
625625

626+
/**
627+
* Adds tabindex="0" to all containers (e.g., <pre>, <div>, etc.) that have overflowing content,
628+
* making them focusable for keyboard navigation accessibility.
629+
*
630+
* This utility is typically used to improve accessibility for code blocks or other scrollable regions,
631+
* allowing users to focus and scroll them using the keyboard.
632+
*/
633+
export function makeOverflowingContainersFocusable() {
634+
document.querySelectorAll('pre,.toggle-tip .wrapper,.viewport.limit-height').forEach(el => {
635+
if (el.scrollWidth > el.clientWidth || el.scrollHeight > el.clientHeight) {
636+
el.setAttribute('tabindex', '0');
637+
}
638+
});
639+
}
640+
626641
/**
627642
* Returns doc set base paths combinations with their configs,
628643
* accounting for set base, version, and/or language.

0 commit comments

Comments
 (0)