Skip to content
Brok UI

Loading…

No results

Skip Link

Open source

A skip link for application layouts: visually hidden until it takes keyboard focus, then it jumps to the main content element.

Version
v1.0.0
Stability
stable
License
MIT
Related
Sidebar
Navigation Menu

Preview

Skip to content

Press Tab: the skip link appears at the top and jumps to the content below.

previews.components.skip-link.default.blade.php Blade
<div class="flex w-full max-w-md flex-col gap-4">
    <x-ui.skip-link target="skip-link-demo-content" />
    <p class="text-sm text-muted-foreground">{{ __('Press Tab: the skip link appears at the top and jumps to the content below.') }}</p>
    <div id="skip-link-demo-content" tabindex="-1" class="rounded-md border border-border p-4 text-sm focus-visible:outline-none focus-visible:ring-[length:var(--ring-width)] focus-visible:ring-ring">
        {{ __('Main content') }}
    </div>
</div>

Installation

terminal
php artisan ui:add skip-link

Registry contract

php artisan ui:add skip-link writes only the files below. The CLI validates each file hash before writing and asks before it replaces a local change, unless you pass --force.

  • blade resources/views/components/ui/skip-link.blade.php
Registry dependencies
None — installs on its own.
Packages
composer: jml/brok:^0.2

Use with AI

A brief for your coding agent: install command, usage, props, guidance and the rules. Copy it, or open a prompt about this component in an assistant.

skip-link.md
# Brok UI: Skip Link (`skip-link`)

A skip link for application layouts: visually hidden until it takes keyboard focus, then it jumps to the main content element.

Brok UI is a Laravel Blade component registry. Installed components are plain Blade files the app owns.

## Install

```bash
php artisan ui:add skip-link
```

## Usage

```blade
<div class="flex w-full max-w-md flex-col gap-4">
    <x-ui.skip-link target="skip-link-demo-content" />
    <p class="text-sm text-muted-foreground">{{ __('Press Tab: the skip link appears at the top and jumps to the content below.') }}</p>
    <div id="skip-link-demo-content" tabindex="-1" class="rounded-md border border-border p-4 text-sm focus-visible:outline-none focus-visible:ring-[length:var(--ring-width)] focus-visible:ring-ring">
        {{ __('Main content') }}
    </div>
</div>
```

## Props

- `target` (string, default `main-content`) — Id of the main content element, with or without the leading #. Give that element tabindex="-1".
- `label` (string|null, default `null`) — Link text; null uses the translated "Skip to content". The default slot wins over it.

## Use when

- Use to orient users and help them move across pages, sections, or commands.
- Placing the first focusable element of an application or site layout, so keyboard users can jump past the navigation to the main content (WCAG 2.4.1).

## Avoid when

- Do not hide primary wayfinding in novelty interactions or deep nested structures if straightforward navigation would be clearer.
- Linking to a section inside the content; use an ordinary link or table-of-contents.

## Anti-patterns

- Hiding primary wayfinding in novelty interactions

## Rules

- Use the `<brok:skip-link>` tag (or `<x-ui.skip-link>`) in Blade; do not rewrite the component.
- Prefer the documented props and variants over utility-class overrides; when a utility must win, use the `!` important modifier.
- Use semantic design tokens (`bg-primary`, `text-muted-foreground`), never raw colour utilities.
- Keep the `data-slot` attributes; they are the styling and test hooks.

## Links

- Docs: https://brokui.dev/docs/components/skip-link
- Registry JSON (files, props, contract): https://brokui.dev/r/open/skip-link.json

Working in Claude Code, Cursor or Codex? Give the agent the whole registry through the MCP server or the Brok UI skill.

Examples

long-content.blade.php Blade
<div class="flex w-full max-w-xs flex-col gap-4">
    <x-ui.skip-link target="skip-link-long-content" :label="__('Skip the navigation and go straight to the list of captured items')" />
    <div id="skip-link-long-content" tabindex="-1" class="rounded-md border border-border p-4 text-sm">{{ __('Main content') }}</div>
</div>

API

manifest knowledge + registry-derived coverage

Props

Props accepted by this component: name, type, default value and description.
Prop Type Default Description
target string main-content Id of the main content element, with or without the leading #. Give that element tabindex="-1".
label string | null null Link text; null uses the translated "Skip to content". The default slot wins over it.

Slots

  • default — Custom link text; wins over label.

Data slots

Stable hooks for CSS overrides and browser tests.

skip-link

Behavior

  • Visually hidden (sr-only) until it has focus; then it shows at the start of the top edge above every layer, including sticky headers and overlays.
  • Pure markup: no JavaScript, no inline style or script, so it works under a strict Content-Security-Policy.
  • Declares registry capability flags: a11y, authoredStateFixtures, responsive, rtl, darkMode, localized.

Guidance

Navigation and orientation

Orient users and move between destinations.

Use when

  • Use to orient users and help them move across pages, sections, or commands.
  • Placing the first focusable element of an application or site layout, so keyboard users can jump past the navigation to the main content (WCAG 2.4.1).

Avoid when

  • Do not hide primary wayfinding in novelty interactions or deep nested structures if straightforward navigation would be clearer.
  • Linking to a section inside the content; use an ordinary link or table-of-contents.

Use instead

  • Visible links and local navigation

Anti-patterns

  • Hiding primary wayfinding in novelty interactions
Anatomy
skip-link
Theming hooks
skip-link

Accessibility

WCAG 2.2 AA Keyboard focus-visible RTL-ready Localized labels Dark mode
Keyboard
native
Focus
native
  • Render it as the first focusable element inside <body>, before the navigation.
  • The target needs tabindex="-1" (for example <main id="main-content" tabindex="-1">) so focus, not only the scroll position, moves to the content.
  • Semantic HTML and a stable data-slot attribute for styling and scripting hooks.
  • Focus-visible rings use the ring token, so keyboard focus is always visible.
  • Disabled and invalid states are conveyed to assistive tech, not by color alone.
  • Targets WCAG 2.2 AA; verify contrast in light, dark, admin and customer surfaces in the preview.
  • Labels go through __() and layout uses logical properties (ms-*, text-start), so it mirrors under dir="rtl" — flip the preview to RTL to confirm.
  • Dark mode uses the same semantic tokens under the dark class; high contrast follows forced-color system tokens.

Livewire

Safe

Livewire can update this component through forwarded wire:* attributes.

Source

The exact, editable file ui:add writes into your app. Previews render this same code; there are no preview-only components.

resources/views/components/ui/skip-link.blade.php Blade
@props([
    // Id of the main content element, without the leading #. Give that
    // element tabindex="-1" so focus moves into it in every browser.
    'target' => 'main-content',
    // Link text. Null uses the translated "Skip to content".
    'label' => null,
])

@php
    // A skip link: the first focusable element of an application layout. It
    // stays visually hidden until it takes keyboard focus, then shows above
    // every layer (the tooltip tier, so a sticky header or an open overlay
    // cannot cover it) at the start edge of the viewport.
    $target = ltrim((string) $target, '#');
    $target = $target !== '' ? $target : 'main-content';
@endphp

<a
    href="#{{ $target }}"
    data-slot="skip-link"
    {{ $attributes->merge(['class' => 'sr-only focus:not-sr-only focus:fixed focus:start-4 focus:top-4 focus:z-tooltip focus:rounded-md focus:bg-primary focus:px-4 focus:py-2 focus:text-sm focus:font-medium focus:text-primary-foreground focus:shadow-lg focus-visible:outline-none focus-visible:ring-[length:var(--ring-width)] focus-visible:ring-ring focus-visible:ring-offset-[length:var(--ring-offset-width)] focus-visible:ring-offset-background']) }}
>{{ $slot->isEmpty() ? ($label ?? __('Skip to content')) : $slot }}</a>

Ownership & lifecycle

Owner, release state, review evidence and adoption for this item.
Owner
Platform UI (@JoshJML)
Current version
1.0.0
Status
Stable
License
open
Accessibility reviewed
No review date recorded
Last breaking change
No date recorded
Deprecation
Not deprecated
Contract
v6
Foundation
≥ 1.0.0