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>Examples
Section titled “Examples”Horizontal
Section titled “Horizontal”orientation="horizontal" scrolls the inline axis and clips the block axis:
<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>API reference
Section titled “API reference”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
| Attribute | Property | Type | Default | Description |
|---|---|---|---|---|
label | label | string | undefined | – | Accessible 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. |
orientation | orientation | "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
| Slot | Description |
|---|---|
| (default) | The scrollable content: it keeps its own semantics and sizes the scroll extent along the declared axis. |
CSS parts
| Part | Description |
|---|---|
viewport | The 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.
| Token | Description |
|---|---|
--ki-motion-duration-fast | Fast interaction transition duration. |
--ki-motion-easing-out | Decelerating interaction transition easing curve. |
--ki-scroller-focus-ring-color | color 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-offset | dimension used by the scroller component for the viewport focus ring offset (ki-dialog precedent). |
--ki-scroller-focus-ring-shadow | shadow 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-width | dimension used by the scroller component for the viewport focus ring width (ki-dialog precedent). |
--ki-scroller-gutter | dimension 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-surface | color 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-color | color 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-length | dimension 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-radius | dimension 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-thickness | dimension 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-color | color 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-inset | dimension 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-body | semantic font family for typography family body. |
Accessibility
Section titled “Accessibility”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.