Navigation
Skip Link
A hidden link that lets keyboard users jump past repeated content.
When to use it: Use it as the first focusable element so keyboard users can bypass navigation (WCAG 2.4.1).
Example
import { SkipLink } from "@comp0/react";
export function Example() {
return (
<div className="flex w-64 flex-col gap-3 text-base text-zinc-800 sm:text-sm dark:text-zinc-100">
<SkipLink
href="#skip-link-main"
className="self-start rounded bg-teal-700 px-3 py-2 text-white outline-offset-2 focus-visible:outline-2 focus-visible:outline-teal-600 dark:bg-teal-400 dark:text-zinc-950 dark:focus-visible:outline-teal-300"
>
Skip to main content
</SkipLink>
<p className="text-zinc-600 dark:text-zinc-400">
Press Tab from the start of this example to reveal the link.
</p>
<nav aria-label="Example" className="flex gap-3">
<a className="underline underline-offset-4" href="#skip-link-home">
Home
</a>
<a className="underline underline-offset-4" href="#skip-link-docs">
Docs
</a>
<a className="underline underline-offset-4" href="#skip-link-blog">
Blog
</a>
</nav>
<main
id="skip-link-main"
tabIndex={-1}
className="rounded border border-zinc-950/10 p-3 dark:border-white/10"
>
Main content starts here.
</main>
</div>
);
}Landmark page shell
Pair the first skip link with native header, nav, main, and footer landmarks.
import { SkipLink } from "@comp0/react";
export function Example() {
return (
<div className="grid min-h-80 grid-cols-[9rem_1fr] grid-rows-[auto_1fr_auto] overflow-hidden rounded-xl border border-zinc-950/15 text-base sm:text-sm dark:border-white/15">
<SkipLink
href="#shell-main"
className="absolute z-10 m-2 rounded bg-teal-700 px-3 py-2 text-white outline-offset-2 focus-visible:outline-2 dark:bg-teal-400 dark:text-zinc-950"
>
Skip to main content
</SkipLink>
<header className="col-span-2 border-b border-zinc-950/10 p-4 font-semibold dark:border-white/10">
Project Atlas
</header>
<nav aria-label="Project" className="border-r border-zinc-950/10 p-4 dark:border-white/10">
<ul className="space-y-2">
<li>
<a href="#overview" className="underline underline-offset-2">
Overview
</a>
</li>
<li>
<a href="#activity" className="underline underline-offset-2">
Activity
</a>
</li>
</ul>
</nav>
<main
id="shell-main"
tabIndex={-1}
className="scroll-mt-4 p-4 outline-teal-600 focus-visible:outline-2 dark:outline-teal-400"
>
<h1 className="text-lg font-semibold">Overview</h1>
<p className="mt-2 text-zinc-600 dark:text-zinc-400">
Native landmarks give assistive technology a map of the page.
</p>
</main>
<footer className="col-span-2 border-t border-zinc-950/10 p-4 text-zinc-600 dark:border-white/10 dark:text-zinc-400">
Project support
</footer>
</div>
);
}Anatomy
Dashed frames are invisible state providers; shaded shapes own real DOM. Numbered pins match the list below.
A wireframe sketch of the assembled component. Each numbered marker matches a part in the list that follows.
SkipLink
Native anchor that stays visually hidden until it receives focus. Owns a DOM element.
Step by step
- 1
Add the main part
Put SkipLink first inside body, before the repeated navigation.
- 2
Add the supporting parts
Point href at the main content, such as "#main".
- 3
Make the behavior clear
Give the target element the matching id and tabIndex={-1} so focus lands there.
Exampletsx <SkipLink href="#main">Skip to main content</SkipLink>;
Keyboard
- ⇥
- Reveals the link when it receives focus.
- ↵
- Jumps to the target and hides the link again.
Forms and accessibility
No form behavior.
Accessibility checklist
- Make it the first focusable element on the page.
- Style the revealed state clearly; it appears exactly when a keyboard user needs it.
- Point href at a real element with a matching id, and give that target tabIndex={-1}.
- Use native header, nav, main, aside, and footer landmarks so assistive technology can navigate the page structure directly.
API reference
import { SkipLink } from "@comp0/react";SkipLink
DOM elementNative anchor that stays visually hidden until it receives focus.
| Prop | Type | Description |
|---|---|---|
href | string | In-page target the link jumps to, such as "#main". |
className | string | Styles the revealed link; merged with the hiding styles while hidden. |
style | CSSProperties | Styles the revealed link; merged with the hiding styles while hidden. |
Style hooks
Attributes that appear while a state is true. Target them with Tailwind data variants such as data-open:bg-zinc-100, or with any CSS selector.
SkipLink
| Style hook | Meaning |
|---|---|
[data-focused] | The link is focused and visible. |
:focus-visible | Native keyboard-focus styling hook. |