---
title: Scrollbar
description: Themed scrollbar styling utility class for overflow containers
visibility: guest
draft: false
---

# Scrollbar

The `.wk-scrollbar` CSS class applies a slim, themed scrollbar to any scrollable element. It uses WireKit's design tokens so the scrollbar automatically matches your theme — including dark mode.

## When to Use

**Use `.wk-scrollbar`** when a scrollable region is part of your UI design — a sidebar nav, a fixed-height panel, a chat history, a code block, a comment thread. The styled scrollbar reinforces the component's boundaries and stays consistent across OS chrome (macOS hides scrollbars by default, Windows shows thick ones — `.wk-scrollbar` equalizes both).

**Don't use `.wk-scrollbar`** on the page-level `<html>` or `<body>` scroll unless you're building a hard-scoped embedded widget — the browser's native scrollbar carries OS-level accessibility affordances (touch handles, high-contrast modes) that users expect to be untouched.

**Don't use it as a general reset.** The class is opt-in per element. If you want project-wide styled scrollbars, apply it to a specific layout container (e.g. your app's `<main>`), not globally.

## Usage

Add the `wk-scrollbar` class to any element with overflow scrolling:

```blade
<div class="wk-scrollbar overflow-auto max-h-64">
    <!-- long content here -->
</div>
```

Works on any scrollable container — `overflow-auto`, `overflow-x-auto`, `overflow-y-auto`, or `overflow-scroll`.

### API Surface

Scrollbar is a **CSS-only utility class**, not a Blade component — there are no props to pass, no PHP class, and no Blade tag. You apply `.wk-scrollbar` to any HTML element that scrolls. All customization happens via the CSS variables listed under "Design Tokens" below.

| What you configure | How |
| --- | --- |
| Width / color / hover color | Design tokens (CSS variables) |
| Which element gets styled | Add `class="wk-scrollbar"` to the element |
| Orientation (horizontal / vertical) | Standard `overflow-x-*` / `overflow-y-*` Tailwind utilities |
| Conditional styling | Combine with any other Tailwind class, responsive variants, etc. |

## Examples

### Vertical Scroll

:::preview{title="Vertical scrollable container"}
<div class="wk-scrollbar" tabindex="0" role="region" aria-label="Sample lines (vertical scroll)" style="overflow-y: auto; max-height: 10rem; border: 1px solid var(--color-wk-border); border-radius: var(--radius-wk-md); padding: 0.75rem; width: 100%; white-space: pre-line;">Line 1 — scroll down to see more
Line 2 — keyboard navigation works (PageDown, End)
Line 3 — Firefox uses scrollbar-width: thin
Line 4 — Chrome and Safari use ::-webkit-scrollbar
Line 5 — thumb color: --color-wk-scrollbar-thumb
Line 6 — track color: --color-wk-scrollbar-track
Line 7 — hover color: --color-wk-scrollbar-thumb-hover
Line 8 — width: --size-wk-scrollbar (6px default)
Line 9 — fully themable via CSS variables
Line 10 — auto-switches with .dark class on ancestor
Line 11 — works on overflow-auto / scroll / x / y
Line 12 — opt-in: add wk-scrollbar to any element
Line 13 — never applied globally to body or html
Line 14 — preserves OS accessibility affordances
Line 15 — high-contrast modes still work as expected
Line 16 — touch handles remain available on mobile
Line 17 — combine with Tailwind responsive variants
Line 18 — pair with overflow-y: auto + max-height
Line 19 — perfect for sidebars, panels, chat history
Line 20 — last line — congratulations, you scrolled!</div>
:::

### Horizontal Scroll

:::preview{title="Horizontal scrollable container"}
<div class="wk-scrollbar" tabindex="0" role="region" aria-label="Sample lines (horizontal scroll)" style="overflow-x: auto; border: 1px solid var(--color-wk-border); border-radius: var(--radius-wk-md); padding: 0.75rem; width: 24rem; max-width: 100%; white-space: nowrap;">
    → scroll horizontally: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
:::

### Textarea

```blade
<x-wirekit::textarea class="wk-scrollbar" rows="4">
    Long content that overflows vertically...
</x-wirekit::textarea>
```

## How It Works

The class provides cross-browser scrollbar styling:

| Browser | Mechanism | Support |
| --- | --- | --- |
| **Firefox** | `scrollbar-width: thin` + `scrollbar-color` | Native thin scrollbar API |
| **Chrome / Edge** | `::-webkit-scrollbar` pseudo-elements | Full width, color, radius control |
| **Safari** | `::-webkit-scrollbar` pseudo-elements | Full width, color, radius control |

## Without the Class

The `.wk-scrollbar` class is opt-in. Elements without it use the browser's default scrollbar. WireKit does **not** override scrollbars globally — you choose where to apply the styling.

::: tip
The WireKit docs site applies scrollbar styling globally to all scrollable elements. If you want the same behavior in your own app, apply `.wk-scrollbar` to your `<body>` or main container — or use the CSS variables directly in your own scrollbar styles.
:::

## Accessibility

- Custom scrollbars do not alter keyboard behavior — `Tab` focuses the scrollable element if it is keyboard-focusable, and the browser handles Arrow, PageUp/Down, Home/End, Space scrolling natively
- No ARIA attributes are added — scrollbars are browser chrome; announcing them via ARIA would be redundant
- When a scrollable region contains **important content that is off-screen on load**, wrap it in a landmark so screen readers can locate it: `<section aria-label="Changelog" class="wk-scrollbar overflow-y-auto">…</section>`
- Firefox's `scrollbar-width: thin` respects OS-level "always show scrollbars" accessibility settings — this component does not force-hide scrollbars
- WCAG 2.1 requires that content remain operable at 200% zoom ([WCAG 1.4.10: Reflow](https://www.w3.org/WAI/WCAG21/Understanding/reflow.html)) — avoid capping `max-height` on containers that users need to scroll through on zoomed viewports

## Keyboard Interaction

This component is purely presentational and does not respond to keyboard input.

## Design Tokens

All scrollbar properties are customizable via CSS variables:

| Variable | Light Default | Dark Default | Description |
| --- | --- | --- | --- |
| `--color-wk-scrollbar-thumb` | neutral-300 | neutral-600 | Thumb (draggable part) color |
| `--color-wk-scrollbar-thumb-hover` | neutral-400 | neutral-500 | Thumb color on hover |
| `--color-wk-scrollbar-track` | transparent | transparent | Track (background) color |
| `--size-wk-scrollbar` | 6px | 6px | Width and height of the scrollbar |

## Customization

Override the tokens in your `app.css` to match your brand:

```css
@layer base {
    :root {
        /* Wider scrollbar with visible track */
        --size-wk-scrollbar: 8px;
        --color-wk-scrollbar-track: var(--color-wk-bg-subtle);

        /* Accent-colored thumb */
        --color-wk-scrollbar-thumb: var(--color-wk-accent);
        --color-wk-scrollbar-thumb-hover: var(--color-wk-accent-hover);
    }
}
```
