Components / More
SkipLink
"Skip to content": the first stop of a page's Tab order. It is hidden until it has focus, then shown at the top-start corner of the window as an accent outline Button. It is a real link, so it works without JavaScript; with it, focus also moves to the target.
Click into the example and press Tab: the link appears at the top-start corner of the window. Enter moves focus to main.
When to useLink to "When to use"
- Every page with a header or navigation before its main content. Put it first in the page, before the header.
Use something else when:
- you use SiteHeader or AppShell: both render a SkipLink already
- the link should stay visible: Link
- any other content should appear only on focus: VisuallyHidden with
focusable
UsageLink to "Usage"
import { SkipLink } from "@arshad-shah/cynosure";
<SkipLink />
<header>…</header>
<main id="main">…</main>
<SkipLink href="#article" labels={{ skip: "Skip to the article" }} />Custom target and textLink to "Custom target and text"
PropsLink to "Props"
| Prop | What it does | Type | Default |
|---|---|---|---|
href | Where the link goes: # and the id of the page's main content. Default "#main". Without JavaScript it is a plain in-page link; with it, focus moves to the target too. | string | "#main" |
labels | Replace the built-in English text: skip, the link text. | Partial<SkipLinkLabels> | |
id | Set on the link element. | string | |
contained | Show at the top-start corner of the nearest positioned ancestor instead of the window's, so the link stays inside a frame such as a side panel (AppShell sets it). Default false. | boolean | false |
className | Added to the link, for layout (e.g. to place it inside a positioned frame). | string | |
style | Layout only. Restyle through --cy-skip-link-* tokens. | CSSProperties |
Generated from the type definitions in @arshad-shah/cynosure 0.5.0.
Behaviour and accessibilityLink to "Behaviour and accessibility"
| Input | Result |
|---|---|
| Tab (first) | Focuses the link and shows it |
| Enter, click | Moves focus to the target; the next Tab continues from there |
| Tab away | Hidden again |
- Without JavaScript: the markup is a plain
<a href="#main">(a Button link), which the browser follows, and it is shown on focus by CSS alone. - Inside a frame:
containedshows it at the corner of the nearest positioned ancestor instead of the window's, so it stays inside a side panel. AppShell sets it. - Focusable target: a target that cannot take focus (
main,div) getstabindex="-1", so it can be focused from script without joining the Tab order. A link, a button or an element with atabindexis left as it is. - The URL: focus moves without changing the URL, so a client-side router is not disturbed. With no element of that id, the browser follows the link as usual.
- Shadow roots: the target is found inside the link's own shadow root too, where a hash link cannot reach.
- Right to left: shown at the top-right corner.
- Sticky headers: give the target a
scroll-margin-topthe height of the header, so it is not scrolled under it.
TouchLink to "Touch"
The shown link is at least 24px tall, and 44px on coarse pointers.
ThemingLink to "Theming"
The shown link is a Button (outline, accent), so the Button tokens style it too.
| Token | What it sets | Default |
|---|---|---|
--cy-skip-link-offset | Distance from the top and inline-start edges of the window | --cy-space-4 |
--cy-skip-link-radius | Corner radius | --cy-radius-md |
createTheme({ components: { skipLink: { offset: "12px", radius: "4px" } } });RelatedLink to "Related"
SiteHeader · AppShell · Button · VisuallyHidden · Link
These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.