WCAG 2.4.11 · Level AA · EN 301 549 9.2.4.11

Focus Not Obscured (Minimum)

Requires that a focused component is not entirely hidden by author-created content such as sticky headers, banners or widgets.

In brief

A sticky header, a cookie banner or a chat widget can cover the element that has keyboard focus. The user presses Tab and focus moves, but the focused element is hidden behind a fixed bar. They cannot see what they are about to activate.

This criterion, new in WCAG 2.2, requires that when a user interface component receives keyboard focus, the component is not entirely hidden due to author-created content. Partial overlap is allowed at this level, but should be kept to a minimum.

What does it cover?

  • What is tested: The focused component, not the focus indicator. If the indicator is entirely hidden, the page would likely also fail 2.4.7.
  • Entirely hidden: At this level the component must not be completely covered. A partly visible component passes, although it is better to avoid overlap.
  • Typical causes: Sticky or fixed headers and footers, cookie banners, chat widgets, floating action buttons and persistent panels.
  • User-opened content: Content the user opens may cover the focused component if the user can reveal it without moving focus, for example by pressing Escape or scrolling.
  • Non-persistent content: Menus, dropdowns, date pickers and tooltips do not fail when they close after use or when focus leaves them.
  • Modal dialogs: A properly built modal takes focus when it opens, so it does not fail.
  • Fixes: Use scroll-padding so that focused elements scroll clear of sticky bars (C43). A sticky header or footer that completely hides focused elements is a failure (F110).
  • Out of scope: The Level AAA version, where no part of the component may be hidden, is 2.4.12. Focus visibility is 2.4.7.

Who does it affect?

Keyboard-only and switch users, who need to see the element they are about to activate. People with low vision who use magnification and have a small view of the page. People who use screen magnifiers and need to keep focus on screen. People with cognitive disabilities who use focus to keep their place.

In the EAA and EN 301 549

The European Accessibility Act (Directive (EU) 2019/882) applies to in-scope products and services placed on the market after 28 June 2025. Recital 47 names four principles for websites and mobile applications: perceivable, operable, understandable and robust. Keeping focus in view is part of "operable".

The technical counterpart is the standard EN 301 549, which incorporates WCAG 2.4.11 by reference and turns it into separate clauses for each kind of ICT.

Where WCAG 2.4.11 appears in EN 301 549
ClauseType of ICTWhat it requires
9.2.4.11Web pagesWeb content must satisfy WCAG success criterion 2.4.11.

Because this criterion is new, check clauses 10 and 11 of V4.1.1 for the rows that apply to documents and software. Clause numbers follow the "9. + WCAG number" pattern of EN 301 549. In V3.2.1 the software clause is divided into further subclauses for open and closed functionality. Check the exact numbers in the standard when you cite them.

Standard version: Criterion 2.4.11 is new in WCAG 2.2, so it is not part of EN 301 549 V3.2.1, which is based on WCAG 2.1. It appears in EN 301 549 V4.1.1 (September 2026), the first version prepared specifically for the EAA. V4.1.1 has not yet been cited in the Official Journal of the European Union, so for now it is best treated as a voluntary technical route to the EAA's requirements. Once cited, it will give a presumption of conformity. It is a Level AA criterion.

A note on EAA scope: Article 2(4) of the Directive excludes certain content from the requirements, for example office file formats published before 28 June 2025 and archives that are not updated after that date. Content you publish or change after that date is not covered by these exclusions.

Directive (EU) 2019/882, EUR-Lex, opens in a new tab

Code examples for the web

1. A sticky header that covers focused elements

When Tab moves focus below a fixed header, the browser may scroll the element only to the top edge, where the header hides it. Add scroll padding equal to the header height (C43).

Incorrect
.site-header { position: sticky; top: 0; height: 72px; }
Correct
.site-header { position: sticky; top: 0; height: 72px; }
html { scroll-padding-top: 88px; } /* header height plus a gap */

2. A sticky footer

Do the same for fixed bars at the bottom.

Incorrect
.sticky-cta { position: fixed; bottom: 0; height: 64px; }
Correct
.sticky-cta { position: fixed; bottom: 0; height: 64px; }
html { scroll-padding-bottom: 80px; }

3. A cookie banner

A banner that covers the page must not hide the focused element. Make it a modal that takes focus, or give the page enough padding.

Incorrect
.cookie-banner { position: fixed; inset: auto 0 0 0; } /* covers focused links */
Correct
<div role="dialog" aria-modal="true" aria-labelledby="ck" class="cookie-banner">
  <h2 id="ck">Cookies</h2>
  <button>Accept</button> <button>Reject</button>
</div>
<!-- Focus moves into the banner and the page behind is inert -->

4. A chat widget or floating button

A button fixed to a corner can cover content. Leave room, or let users move it.

Incorrect
.chat { position: fixed; right: 0; bottom: 0; width: 320px; height: 400px; }
Correct
.chat { position: fixed; right: 1rem; bottom: 1rem; }
.chat[hidden] { display: none; } /* closed by default; opens on request */

5. A dialog the user can dismiss

A panel the user opens may overlap content if they can close it with Escape without losing focus.

Incorrect
<div class="panel">…</div> <!-- no way to close it -->
Correct
panel.addEventListener("keydown", e => {
  if (e.key === "Escape") { panel.hidden = true; trigger.focus(); }
});

6. Scroll into view on focus

If a script manages scrolling, make sure the focused element ends up clear of any fixed bar.

Incorrect
el.focus({ preventScroll: true }); // stays under the header
Correct
el.focus();
el.scrollIntoView({ block: "center" });

Code examples for mobile

On mobile, the on-screen keyboard, a bottom bar or a floating button can cover a focused field. Make sure the focused field stays in view.

iOS (SwiftUI)

import SwiftUI

struct CommentForm: View {
    @FocusState private var focusedField: Field?
    enum Field: Hashable { case name, comment }
    @State private var name = ""
    @State private var comment = ""

    var body: some View {
        ScrollViewReader { proxy in
            ScrollView {
                VStack(spacing: 16) {
                    TextField("Name", text: $name)
                        .id(Field.name)
                        .focused($focusedField, equals: .name)
                    TextEditor(text: $comment)
                        .id(Field.comment)
                        .frame(height: 120)
                        .focused($focusedField, equals: .comment)
                }
                .padding()
            }
            // Scroll the focused field clear of the keyboard and bars
            .onChange(of: focusedField) { field in
                if let field { withAnimation { proxy.scrollTo(field, anchor: .center) } }
            }
        }
    }
}

Android (Jetpack Compose)

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.relocation.BringIntoViewRequester
import androidx.compose.foundation.relocation.bringIntoViewRequester
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.OutlinedTextField
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import kotlinx.coroutines.launch

@OptIn(androidx.compose.foundation.ExperimentalFoundationApi::class)
@Composable
fun CommentForm() {
    var comment by remember { mutableStateOf("") }
    val requester = remember { BringIntoViewRequester() }
    val scope = rememberCoroutineScope()

    Column(
        Modifier.verticalScroll(rememberScrollState()).imePadding() // keep clear of the keyboard
    ) {
        OutlinedTextField(
            value = comment,
            onValueChange = { comment = it },
            modifier = Modifier
                .bringIntoViewRequester(requester)
                .onFocusChanged { if (it.isFocused) scope.launch { requester.bringIntoView() } }
        )
    }
}

How to test

  • Tab through a long page: Watch where focus lands as you tab down the page. Is the focused element ever completely hidden behind a sticky header, footer, banner or widget?
  • Tab backwards as well: Shift+Tab can scroll an element under a header at the top.
  • Check with the banner open: Load the page with the cookie banner and any chat widget visible, and tab through the page.
  • Test at small sizes and zoom: Narrow windows and 200% or 400% zoom make fixed bars cover more of the page.
  • Check dialogs and menus: Does a modal take focus? Can the user dismiss user-opened content with Escape?
  • Check the CSS: Look for position: sticky and position: fixed elements and whether scroll-padding is set.
  • Check mobile: Focus fields near the bottom of the screen. Does the keyboard or a bottom bar cover them?
  • Use a checker as a starting point: Automated tools cannot see what is covering what as focus moves. A person must tab through the page.

Common mistakes

  • A tall sticky header with no scroll padding: The most common cause of failure (F110).
  • A cookie banner that covers the page and takes no focus: Users tab behind it.
  • A chat widget that opens over content by default: It hides links and fields.
  • Sticky bars at both top and bottom on small screens: Little of the page remains.
  • Using preventScroll carelessly: Focus moves but the page does not scroll.
  • Only testing at desktop width: Mobile layouts overlap more.
  • Assuming partial overlap is always fine: It passes at AA but still hurts users, and Level AAA 2.4.12 forbids it.
  • A dialog that cannot be dismissed: User-opened content must be dismissible without moving focus.

Sources

Standard version: EN 301 549 V4.1.1 (2026-09), WCAG 2.2. This page is for informational purposes only and is not legal advice. For binding requirements, refer to the official texts of the European Accessibility Act (Directive (EU) 2019/882) and EN 301 549.

Corpowid is recognized by Gartner

Corpowid has been recognized by Gartner, a leading global research and advisory firm, for our innovation and performance in digital accessibility. These badges reflect our commitment to creating inclusive, AI-powered web experiences.

Have questions about Corpowid?

Let’s connect.

We will get back to you as soon as possible.