Stop Fixed Bottom Banners From Covering Focused Content
A persistent 72-pixel bottom banner covers the final focused action after end-aligned scrolling, leaving the control and its focus indicator unavailable to keyboard users.
scroll-margin: 0- Viewport height
- --
- Target bottom
- --
- Banner overlap
- --
scroll-margin-bottom: 80px- Viewport height
- --
- Target bottom
- --
- Banner overlap
- --
Three-browser evidence verified. Live values come from your current browser. The formal matrix records the controlled browser runs and fixture revision used for the published conclusion.
Observed failure
The final action is underneath the bottom banner
End-aligned scrolling places the 44-pixel action at the viewport edge while a 72-pixel fixed banner occupies that same area. The authored overlay completely covers the focused control.
Minimal code diff
Reserve an unobscured end position
Provide enough block-end space and scroll margin for the persistent banner so focus-driven scrolling stops above it. Unfixing or dismissing the banner may be better on constrained heights.
Before
.final-action {
scroll-margin-block-end: 0;
}After
.page { padding-block-end: 80px; }
.final-action {
scroll-margin-block-end: 80px;
}Root cause
Fixed positioning removes the banner from normal flow and pins it to the viewport. The document therefore does not automatically reserve space for the overlay. When a focus or scrolling operation aligns the final action with the block-end edge, the banner paints above it.
The fixed fixture combines block-end page space with a matching scroll margin. The page can scroll far enough to place the action above the banner, and focus-driven scrolling uses that reserved position.
Measure visible clearance after focus moves
Tab to the last action and compare its bounding rectangle with the banner’s block-start edge. The important value is the clearance after the browser has scrolled the focused element into view; checking the initial page position can miss the failure. The fixture records a deficit when any part of the action or its focus indicator occupies the banner’s painted region.
Test the banner with its longest translation, error state, and increased text size rather than assuming a permanent 72-pixel height. Also test short landscape viewports and reverse keyboard navigation. If the overlay height is dynamic, derive the reserved space from the actual component or choose a non-fixed layout at constrained heights instead of copying the fixture’s numeric offset.
When this fix is not enough
A fixed offset becomes stale if the banner wraps, grows after localization, or shares the edge with browser UI. On short or landscape viewports, unfixing the banner through a height media query may preserve more usable content. Optional notices can also provide a real close control, but required consent choices need an interaction and focus model appropriate to their legal purpose.
Regression condition
At each recorded viewport, the failing focused action must have positive block-end clearance deficit relative to the banner. The fixed action must end above the banner with zero deficit and retain focus. Both states must have zero page-level horizontal overflow.
Primary references
Sources checked for this case
- C34: Using media queries to un-fix sticky headers and footers - W3C Web Accessibility Initiative, checked 2026-08-04
- Understanding Success Criterion 2.4.11: Focus Not Obscured (Minimum) - W3C Web Accessibility Initiative, checked 2026-08-04
- F110: Sticky content completely hiding focused elements - W3C Web Accessibility Initiative, checked 2026-08-04
Formal evidence
Browser and viewport matrix
Cells show failing / fixed fixed-banner clearance deficit in CSS pixels.
| Browser | 320 | 375 | 768 | 1024 | 1440 |
|---|---|---|---|---|---|
| Chromium | +72 / +0 | +32 / +0 | +0 / +0 | +0 / +0 | +0 / +0 |
| Firefox | +72 / +0 | +32 / +0 | +0 / +0 | +0 / +0 | +0 / +0 |
| WebKit | +72 / +0 | +32 / +0 | +0 / +0 | +0 / +0 | +0 / +0 |
18/18 recorded assertions passed
chromium-failing-overlap-32072pxchromium-fixed-overlap-3200pxchromium-horizontal-reflow-3200px / 0pxchromium-failing-overlap-37532pxchromium-fixed-overlap-3750pxchromium-horizontal-reflow-3750px / 0pxfirefox-failing-overlap-32072pxfirefox-fixed-overlap-3200pxfirefox-horizontal-reflow-3200px / 0pxfirefox-failing-overlap-37532pxfirefox-fixed-overlap-3750pxfirefox-horizontal-reflow-3750px / 0pxwebkit-failing-overlap-32072pxwebkit-fixed-overlap-3200pxwebkit-horizontal-reflow-3200px / 0pxwebkit-failing-overlap-37532pxwebkit-fixed-overlap-3750pxwebkit-horizontal-reflow-3750px / 0px
Run 2026-08-04T11-36-57-234Z. chromium 149.0.7827.201, firefox 153.0, webkit 26.5. Open raw manifest