Skip to content
Kimenpre-v1
Color scheme

Component

ki-scroller

A bounded scroll container that clips its content along one declared axis and replaces platform scrollbar chrome with a token-resolved indicator — chat panes, log blocks, tag rows, tall menus inside cards. Its size comes entirely from your layout; scrolling stays native (wheel, touch, keyboard, indicator drag).

1.4.0 — Adds the scroller component.

1.3.2 — Fixes focus retention in dialogs.

1.3.1 — Corrects RTL thumb travel in switches.

1.3.0 — Introduces the motion token family.

1.2.0 — Ships the material3 reference theme.

1.1.0 — Adds form-associated custom elements.

1.0.0 — First stable release.

<ki-scroller label="Release notes" style="block-size: 8rem;">
<p>1.4.0 — Adds the scroller component.</p>
<p>1.3.2 — Fixes focus retention in dialogs.</p>
<p>1.3.1 — Corrects RTL thumb travel in switches.</p>
<p>1.3.0 — Introduces the motion token family.</p>
<p>1.2.0 — Ships the material3 reference theme.</p>
<p>1.1.0 — Adds form-associated custom elements.</p>
<p>1.0.0 — First stable release.</p>
</ki-scroller>

orientation="horizontal" scrolls the inline axis and clips the block axis:

alert avatar badge button card checkbox dialog divider indicator input progress tooltip
<ki-scroller label="Component tags" orientation="horizontal" style="inline-size: 100%;">
<div style="display: flex; gap: 0.5rem; inline-size: max-content;">
<ki-badge tone="info">alert</ki-badge>
<ki-badge tone="info">avatar</ki-badge>
<ki-badge tone="info">badge</ki-badge>
<ki-badge tone="info">button</ki-badge>
<ki-badge tone="info">card</ki-badge>
<ki-badge tone="info">checkbox</ki-badge>
<ki-badge tone="info">dialog</ki-badge>
<ki-badge tone="info">divider</ki-badge>
<ki-badge tone="info">indicator</ki-badge>
<ki-badge tone="info">input</ki-badge>
<ki-badge tone="info">progress</ki-badge>
<ki-badge tone="info">tooltip</ki-badge>
</div>
</ki-scroller>

When to use: a bounded region inside a view whose content can outgrow it: chat or message panes, code and log blocks, tag rows, sidebar navigation, tall menus inside cards. Give it bounds (its size comes entirely from your layout) and a label (required: the accessible name of the scroll region). Scrolling stays native — wheel, touch, keyboard and indicator drag operate the viewport directly.

When not to use: page-level scrolling (the browser's job), carousels or paginated media (future indicator/carousel patterns), virtualized long collections, multi-column tabular data, or nesting scrollers (v1 guarantees a single scroll axis per region). Cross-axis overflow is an authoring mistake: the scroller scrolls its declared axis only and clips the other — wrap or size content on the cross axis.

Properties & attributes

AttributePropertyTypeDefaultDescription
labellabelstring | undefinedAccessible name of the scroll region ("Release notes", "Chat messages"). Assistive technology receives a region with this name whose slotted content keeps its own semantics (FR-006). Documented as required: a scroller without a label renders but exposes no accessible name and fails the accessibility audit (015-ki-progress precedent). The label is never rendered visually.
orientationorientation"horizontal" | "vertical"'vertical'Declared scroll axis, mapping the design source's Type axis: vertical (default) scrolls the block axis, horizontal the inline axis. One axis per instance; the cross axis clips. A structural axis, never appearance — thickness, shape and colors of the indicator are per-theme --ki-scroller-* tokens. An unrecognized value matches no style selector and no horizontal code path, so the scroller keeps the default vertical behavior (fallback by CSS construction plus a single strict comparison — no validation code, FR-002/FR-009).

Slots

SlotDescription
(default)The scrollable content: it keeps its own semantics and sizes the scroll extent along the declared axis.

CSS parts

PartDescription
viewportThe scroll viewport: surface, focus ring and, as native scrollbar chrome styled from --ki-scroller-* tokens, the indicator.

CSS custom properties

The public styling contract of ki-scroller: reassign these tokens at :root or on a subtree — never override internals.

TokenDescription
--ki-motion-duration-fastFast interaction transition duration.
--ki-motion-easing-outDecelerating interaction transition easing curve.
--ki-scroller-focus-ring-colorcolor used by the scroller component for the viewport focus ring: the keyboard-focusable scroll region (FR-005) adopts the ki-dialog focus-ring pair verbatim.
--ki-scroller-focus-ring-offsetdimension used by the scroller component for the viewport focus ring offset (ki-dialog precedent).
--ki-scroller-focus-ring-shadowshadow used by the scroller component for the viewport focus ring glow (MarsUI Focus/primary 3px 20%-alpha halo, the ki-button double mechanism; completes the theming hook ki-scroller.css already consumes).
--ki-scroller-focus-ring-widthdimension used by the scroller component for the viewport focus ring width (ki-dialog precedent).
--ki-scroller-gutterdimension used by the scroller component for the clearance on each side of the thumb: the 2px padding-inline of the 8px Scroller rail (rail thickness = thumb-thickness + 2×gutter).
--ki-scroller-surfacecolor used by the scroller component for the viewport surface: transparent in onmars — the scroller shows the consumer's own surface; a theme may resolve a proper surface here (FR-007).
--ki-scroller-thumb-colorcolor used by the scroller component for the indicator thumb: Inverse_white/alpha_6, the exact variable bound to the scroll pill on both Scroller variants (Black/5 light, White/5 dark) — the scheme flip rides the semantic layer (specs/023-ki-scroller/design-extraction.md).
--ki-scroller-thumb-min-lengthdimension used by the scroller component for the minimum thumb length along the scroll axis: the 16px min-height on the Figma scroll pill; the actual length stays the native visible-fraction proportion (FR-003).
--ki-scroller-thumb-radiusdimension used by the scroller component for the thumb shape: Radius/radius_round bound in Figma — the pill is a radius token, never an attribute (002 shape precedent).
--ki-scroller-thumb-thicknessdimension used by the scroller component for the thumb cross size: the 4px pill measured inside the 8px MarsUI rail (rail = thumb + 2×gutter, verified 2026-07-17).
--ki-scroller-track-colorcolor used by the scroller component for the track: the MarsUI pill floats directly on the content surface with no visible track — transparent in onmars; a theme opts into a visible track through this token, never an attribute.
--ki-scroller-track-insetdimension used by the scroller component for the rail end insets: Space/xs bound as the 4px padding along the scroll axis of both Scroller variants (design-extraction §Decisiones 5).
--ki-typography-family-bodysemantic font family for typography family body.

label is required — it names the scroll region for assistive technology. The scroller scrolls its declared axis only and clips the other; cross-axis overflow is an authoring mistake (wrap or size content on the cross axis). Page-level scrolling remains the browser’s job.

Open ki-scroller in Storybook