Skip to main content

rc-scroller

Native scroll region with an optional centered content layout and fullbleed track. The custom element host is the scrollport, so native scrolling APIs, events, restoration, and observers work without reaching into shadow DOM.

Package
@rcarls/rc-scroller
Element
<rc-scroller>
Native dependency
Custom element host is the native scrollport
State model
Declarative axis and layout
Main events
scroll (native)

Installation​

npm install @rcarls/rc-webcomponents@next
import '@rcarls/rc-webcomponents/rc-scroller/define';

Usage​

<rc-scroller layout="content" role="region" aria-label="Recipes">
<header data-rc-scroller-span="fullbleed">Recipes</header>
<article>Apple pie</article>
</rc-scroller>

Give the host a definite block size, or place it in a layout that provides one, when it should scroll. axis accepts block (the default), inline, or both. The component does not add a landmark, accessible name, or tab stop; authors add those semantics only when the surrounding document needs them.

Live demo​

Accessibility​

The scroller is a plain native scroll region: it adds no role, accessible name, or tabindex. When the region needs a name or a landmark, add them yourself. Some browsers make a scroll region with no focusable content keyboard-focusable on their own; add tabindex="0" when keyboard users must scroll such content in every browser.

Content layout​

Set layout="content" to place direct children on a centered content track. The track uses --rc-scroller-content-padding-inline for its minimum gutters and --rc-scroller-content-max-inline-size for its maximum width. A direct child with data-rc-scroller-span="fullbleed" spans the entire available inline size while preserving source order.

Without layout="content", the component only establishes a native scrollport. It does not impose padding or child layout.

Scroll-boundary state​

at-block-start, at-block-end, at-inline-start, and at-inline-end are reflected, read-only attributes: present when scrolled to (within a few pixels of) that edge on an enabled axis, or when that axis isn't scrollable at all (nothing more to reveal counts as already at both of its edges). Style an edge affordance from outside the shadow root by targeting the attribute directly, for example an edge-fade mask on an inline scroller:

Initial boundary state settles in the first animation frame after mount. This keeps a batch of scrollers from alternating layout reads with reflected-state writes while the route is still being inserted.

rc-scroller[axis='inline'] {
mask-image: linear-gradient(
to right,
transparent,
black 24px,
black calc(100% - 24px),
transparent
);
}

rc-scroller[axis='inline'][at-inline-start] {
mask-image: linear-gradient(to right, black calc(100% - 24px), transparent);
}

rc-scroller[axis='inline'][at-inline-end] {
mask-image: linear-gradient(to right, transparent, black 24px);
}

The component only tracks and reflects this state: it makes no visual decision of its own about how, or whether, to show it.

API​

Properties​

PropertyMarkupTypeDefaultDescription
axisaxisRCScrollerAxis'block'Scroll axis.
layoutlayoutRCScrollerLayout'none'Optional child layout.
atBlockStartat-block-startbooleantrueReflected, computed. See the class doc comment.
atBlockEndat-block-endbooleantrueReflected, computed. See the class doc comment.
atInlineStartat-inline-startbooleantrueReflected, computed. See the class doc comment.
atInlineEndat-inline-endbooleantrueReflected, computed. See the class doc comment.

Slots​

NameDescription
(default)Scrollable content.

CSS Custom Properties​

PropertyDefaultDescription
--rc-scroller-overscroll-behaviorcontainOverscroll behavior on enabled axes.
--rc-scroller-overflow-anchorautoBrowser scroll anchoring behavior.
--rc-scroller-scrollbar-widthautoScrollbar width.
--rc-scroller-scrollbar-colorautoScrollbar thumb and track colors.
--rc-scroller-content-padding-inline1remMinimum inline gutter in content layout.
--rc-scroller-content-max-inline-size100%Maximum width of the content track.
--rc-scroller-content-row-gap0Gap between rows in content layout.

CSS Parts​

PartDescription
contentWrapper for the default slot and optional layout grid.