Press Tab on a page with a sticky header and keep going past the fold. Sooner or later the focused link scrolls into view underneath the header. The keyboard user has no idea where they are.
Since WCAG 2.2 this is an AA failure with its own number: 2.4.11 Focus Not Obscured (Minimum). W3C's words: "When a user interface component receives keyboard focus, the component is not entirely hidden due to author-created content." The usual causes are named in the Understanding document: "sticky footers, sticky headers, and non-modal dialogs", and a cookie banner "will fail this success criterion if it entirely obscures a component receiving focus".
Why it happens
When an element gets focus off screen, the browser scrolls just far enough to bring it into the viewport. It knows nothing about your position: sticky or position: fixed header, so it happily parks the element at the very top, behind the bar.
The fix
Tell the scroll container how much of it is covered:
:root {
--header-height: 4rem;
}
html {
scroll-padding-top: var(--header-height);
}
.site-header {
position: sticky;
top: 0;
height: var(--header-height);
}
scroll-padding defines an inset that scrolling into view respects, so the focused element stops below the header instead of under it. The same property fixes in-page anchor links (#section) landing under the header, so you get two bugs for one line.
A cookie banner or chat button fixed to the bottom needs the other side too:
html {
scroll-padding-bottom: 6rem; /* height of the bottom banner */
}
If the scrolling happens inside a panel rather than the page, put scroll-padding on that panel, since it applies to the element that scrolls.
Test it in 30 seconds
- Load the page fresh, with the cookie banner still showing.
- Click the address bar, then press Tab until focus is past the first screen.
- Every focused element should be at least partly visible. Minimum means not entirely hidden, but aim for fully visible, which is what 2.4.12 asks for at AAA.
- Press Shift + Tab back up, because upward scrolling can hide things under a bottom banner.
Automated scanners mostly can't catch this, because it depends on scroll position and on which element has focus at that moment. It is one of the nine steps in a manual keyboard pass: how to test keyboard accessibility by hand.
Top comments (0)