Skip link
WCAG 2.4.1. First thing in the tab order, invisible until focused.
Code
The three render the same class names, the same ARIA and the same data attributes. That is checked when this site builds: a class in any of these samples that neither the markup contract nor the shipped stylesheet defines fails the build.
<body>
<a class="wsu-skip-link" href="#main">Skip to main content</a>
…
<main class="wsu-shell__main" id="main" tabindex="-1">…</main>
</body>{{-- Rendered by <x-wsu::app-shell> unless you set wayne-ui.skip_link to false --}}
<x-wsu::skip-link target="main" /><SkipLink target="main" />Why it works this way
- Render it before anything else in body. A skip link that comes after the navigation it exists to skip is decoration.
- Its target needs tabindex="-1", or the browser scrolls without moving focus and the next Tab returns to the top of the page.
Accessibility
- Bypass Blocks (2.4.1).
- Visible on focus, which is what makes it a control rather than a hidden string (2.4.7).
Success criteria in brackets refer to WCAG 2.2. Every one of them is checked by axe-core in both themes at three viewport widths before this page can be published. See Accessibility for what the gates are.
Props
Blade
| Attribute | Default | What it does |
|---|---|---|
target | 'main' | id of the element focus should land on. |
Vue
| Prop | Type and default | What it does |
|---|---|---|
target | String, 'main' | Must match AppShell's mainId. |
In the markup contract
contract/markup-contract.json is extracted from the two static templates and every package tests against it. This is what it records for .wsu-skip-link.
| Template | Elements | Accessibility attributes | Uses |
|---|---|---|---|
| internal apps/examples/static-html/index.html | a | none recorded | 1 |
| public apps/examples/static-html/public-app.html | a | none recorded | 1 |