In lesson 2.1.7, you made the Kladde’s static prototype accessible: landmarks, headings, labels, a visible focus. Since then, the Kladde has become a Blazor app, and Blazor brings things that a static page doesn’t know. The page changes without reloading; where does the focus go then? An island changes its content; whoever isn’t looking doesn’t notice. A form submits and comes back with errors; where do you find out?

This lesson goes through these questions one after the other and ends with a check of all the pages. The goal remains WCAG 2.2, level AA.

Focus after navigation

On an ordinary website, every link loads a new page. The screen reader reads out the new title, and the focus is at the start. With an enhanced navigation, Blazor swaps only the content (lesson 2.5.11). The focus stays on the link you just clicked, or falls into nothing if that link no longer exists on the new page. Whoever can’t see doesn’t learn that something has changed.

For that there is the component FocusOnNavigate. It belongs in Components/Routes.razor, next to the RouteView; in lesson 2.5.1 you still left it out there:

Razor
<Router AppAssembly="typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
    <Found Context="routeData">
        <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
        <FocusOnNavigate RouteData="routeData" Selector="h1" />
    </Found>
</Router>

Selector="h1" is a CSS selector: After a page change, the first h1 gets the focus. A screen reader reads it out, and the person knows where they are. Every page of the Kladde has exactly one h1, namely the one from PageHeader.

With static SSR, the component renders no C# behavior but an element that blazor.web.js works with:

<blazor-focus-on-navigate selector="h1"></blazor-focus-on-navigate>

When blazor.web.js sets the focus, the documentation says only briefly. In .NET 10’s script, you can read it up exactly, and it is worth it, because it explains observations that otherwise seem strange:

Case What happens
The page is loaded completely If no element has the focus yet and no element carries autofocus, the h1 gets the focus.
Enhanced navigation to a different path After the swap, the h1 gets the focus.
Enhanced navigation with only a different query, such as ?page=2 The focus stays where it is.
The person sets the focus themselves during the navigation It stays there.

A heading is not an element that can otherwise be focused. blazor.web.js therefore gives it tabindex="-1" before it focuses it; that doesn’t put it in the Tab key’s order. Whether the browser shows the :focus-visible outline from lesson 2.1.7 on the heading depends on how you got there: usually not after a mouse click, usually yes after the keyboard.

And the skip link from lesson 2.5.3? It stays. When paging with ?page=2, the focus doesn’t move, and whoever goes up with Shift+Tab finds it as the first element.