Any sticky header, footer, cookie banner, or chat widget that overlaps a focused element by even one pixel fails this Level AAA criterion -- the strict counterpart to 2.4.11.
2.4.12 Focus Not Obscured (Enhanced)
In Plain Language
[2.4.12 Focus Not Obscured (Enhanced)] is new in WCAG 2.2 at Level AAA[1]. When a user interface component receives keyboard focus, no part of that component may be hidden by author-created content -- sticky headers, fixed footers, cookie banners, non-modal dialogs, and chat widgets must not overlap the focused element at all.
2.4.12 is the strict counterpart to 2.4.11 Focus Not Obscured (Minimum)[2]. 2.4.11 (Level AA) passes as long as some part of the focused element remains visible. 2.4.12 (Level AAA) fails on a single pixel of overlap with author content.
Why It Matters
- Partial occlusion hides load-bearing context. A button whose label reads "Delete" when the word "permanently" is clipped by a sticky footer invites destructive mis-activation.
- Screen magnifier users render a narrow viewport at high zoom. A sticky header that clips the top of a focused field can leave the magnified region showing only the overlay, stripping the focus indicator and the accessible name from the user's view at once.
- Sighted keyboard users track the focus ring as a positional anchor. When the ring is partially covered, the user loses the pixel-level confirmation that 2.4.7 Focus Visible exists to provide -- which is why 2.4.12 treats the entire component, not only the indicator, as off-limits to overlap[1].
- Semi-opaque overlays are explicitly out of scope for 2.4.12 (they are treated under contrast criteria), but any opaque content on top of the focused component is a failure[1].
Examples
Tab through these links -- the entire focus ring stays visible:
First linkSecond link
Third link
✔ scroll-padding-top accounts for both sticky header height and outline-offset so nothing is obscured
/* scroll-padding-top MUST equal the full height of every sticky overlay
plus the focus ring outline-width and outline-offset. For 2.4.12, any
residual overlap is a failure -- budget generously. */
html {
scroll-padding-top: 5rem; /* 3.5rem header + 0.25rem outline + 0.5rem buffer */
}
header {
position: sticky;
top: 0;
height: 3.5rem;
z-index: 10;
}
:focus-visible {
scroll-margin-top: 5rem; /* matches scroll-padding-top on the container */
outline: 3px solid rgba(26, 107, 90, 0.5);
outline-offset: 4px;
}
Tab to the link below -- its focus ring is clipped by the footer:
✘ The focus ring is partially covered by the fixed footer -- passes 2.4.11 but fails 2.4.12
How to Fix It
- Match
scroll-paddingto the full overlay height. 2.4.11 tolerates partial visibility, soscroll-padding-toponly has to clear enough of a sticky header to leave something showing. 2.4.12 requires the padding to equal the sticky element's full height plusoutline-widthandoutline-offset. Compute it from the real rendered height, not a guess. - Set
scroll-margin-top/scroll-margin-bottomon focusable elements. When the browser scrolls a focused element into view, it honoursscroll-marginon the target. Apply it via:focus-visible(or a global selector on interactive elements) so programmatic focus moves land outside every sticky region, not just the one closest to the viewport edge. - Dismiss, collapse, or exclude overlays from the focus path. Cookie banners and chat widgets that auto-collapse on first Tab keep the sticky region small enough for the padding math to stay valid. If an overlay cannot be dismissed, its height must be added to
scroll-paddingfor the duration it is on screen. - Recompute on viewport and layout change. Sticky-element heights change with responsive breakpoints, font-size preferences, and dismissible banners. Use a
ResizeObserveron each sticky container and write its current height to a CSS custom property thatscroll-paddingconsumes. - Audit with the keyboard, not just the mouse. Tab through every interactive element at the breakpoints you ship (mobile, tablet, desktop) and at 200% zoom. Any focus ring or component edge clipped by a sticky region is a 2.4.12 failure even if 2.4.11 would pass.
- Check z-index stacking. An overlay with a higher
z-indexthan the focused element's nearest stacking context will paint over it regardless of scroll math. Keep sticky chrome in a dedicated stacking layer and verify no author content can float above the content region where focus lives.
References
- [1] W3C (2023). Understanding Success Criterion 2.4.12: Focus Not Obscured (Enhanced). W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-enhanced.html ↩ ↩ ↩
- [2] W3C (2023). Understanding Success Criterion 2.4.11: Focus Not Obscured (Minimum). W3C, Accessed 2026-04-07. https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html ↩