# scrollbar-color

> Themes a scroll container's scrollbar via the standard `scrollbar-color` property, supported by Firefox and modern Chromium alike through plain CSS.

```ts
import { scrollbarColor } from "@sdxc/u/overflow";
```

Themes a scroll container's scrollbar via the standard `scrollbar-color`
property, supported by Firefox and modern Chromium alike through plain
CSS. Inherits down the tree, theming nested scroll containers too.

## Quick reference

Every documented call, beside the CSS it emits.

| Call | CSS |
| --- | --- |
| `u.scrollbarColor()` | `css({ scrollbarColor: "auto" })` |
| `u.scrollbarColor("neutral")` | `css({ scrollbarColor: "var(--ui-neutral-border) transparent" })` |
| `u.scrollbarColor("brand.strong", "neutral")` | `css({ scrollbarColor: "var(--ui-brand-border-strong) var(--ui-neutral-bg-tint)" })` |
| `u.scrollbarColor("color.neutral.400", "color.neutral.100")` | `css({ scrollbarColor: "var(--ui-color-neutral-400) var(--ui-color-neutral-100)" })` |

## Examples

### Basic example

Use `scrollbarColor("neutral")` to color the scrollbar thumb with a tone, leaving the track transparent. Scroll the box, or set your system to always show scrollbars, to see it:

```tsx
<div
	mix={[scroll("y"), scrollbarColor("neutral"), bs(24), is(72), maxIs("100%"), ...]}
>
	<p mix={[...]}>
		This paragraph is taller than its box, so the last lines of it do not fit. Scroll to read
		the rest, while the page around the box stays exactly where it is.
	</p>
</div>
```

### Thumb and track

Pass a second color to paint the track too, like `scrollbarColor("brand.strong", "neutral")`:

```tsx
<div
	mix={[
		scroll("y"),
		scrollbarColor("brand.strong", "neutral"),
		bs(24),
		is(72),
		maxIs("100%"),
		...,
	]}
>
	<p mix={[...]}>
		This paragraph is taller than its box, so the last lines of it do not fit. Scroll to read
		the rest, while the page around the box stays exactly where it is.
	</p>
</div>
```

### Using palette shades

Pass palette paths, like `scrollbarColor("color.brand.500", "color.brand.100")`, for exact shades:

```tsx
<div
	mix={[
		scroll("y"),
		scrollbarColor("color.brand.500", "color.brand.100"),
		bs(24),
		is(72),
		maxIs("100%"),
		...,
	]}
>
	<p mix={[...]}>
		This paragraph is taller than its box, so the last lines of it do not fit. Scroll to read
		the rest, while the page around the box stays exactly where it is.
	</p>
</div>
```

## Applying on a state

Wrap the call in a state utility to scope it to one selector.

```ts
u.hover(u.scrollbarColor())
```

## Responsive design

Wrap the call in a container query to scope it to one width.

```ts
u.at("md", u.scrollbarColor())
```

## Customizing your theme

### Customizing colors

Define a palette as `--ui-color-{name}-{50..950}` and map a tone onto it with the `--ui-{tone}-*` variables, the way `theme.css` maps the built-in ones:

```css
:root {
	--ui-color-info-50: oklch(0.97 0.02 230);
	--ui-color-info-200: oklch(0.88 0.06 230);
	--ui-color-info-500: oklch(0.62 0.16 230);
	--ui-color-info-600: oklch(0.52 0.18 230);
	--ui-color-info-900: oklch(0.3 0.1 230);

	--ui-info-bg-tint: var(--ui-color-info-50);
	--ui-info-bg-solid: var(--ui-color-info-600);
	--ui-info-fg: var(--ui-color-info-600);
	--ui-info-fg-muted: var(--ui-color-info-500);
	--ui-info-fg-emphasis: var(--ui-color-info-900);
	--ui-info-fg-on-solid: white;
	--ui-info-border: var(--ui-color-info-200);
	--ui-info-border-strong: var(--ui-color-info-600);
	--ui-info-ring: var(--ui-color-info-500);
}
```

```ts
declare module "@sdxc/u" {
	interface ColorPalettes {
		info: true;
	}
	interface SemanticTones {
		info: true;
	}
}
```

The new name is then accepted wherever the scale is:

```ts
scrollbarColor("info")
```

## Signature

```ts
u.scrollbarColor(thumb?: ColorValue | (string & {}), track?: ColorValue | (string & {}))
```
