Interactive
Infinite scroll
A sentinel that fires monsoon:load when it nears the viewport or a scroll container. Append the next items, then call detail.done(), or detail.done(false) at the end. Needs monsoon.js.
Needs monsoon.js. The styles work on their own, and the behavior comes from the optional interactive layer: add <script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script> or import 'monsooncss/js'. See the interactive layer.
Example
<div id="feed-js" class="max-h-64 overflow-y-auto rounded-xl border p-3 grid gap-2 max-w-sm">
<article class="rounded-lg border bg-surface p-3 text-sm">Post 1</article>
<article class="rounded-lg border bg-surface p-3 text-sm">Post 2</article>
<article class="rounded-lg border bg-surface p-3 text-sm">Post 3</article>
<article class="rounded-lg border bg-surface p-3 text-sm">Post 4</article>
<div class="infinite-scroll" data-m-infinite-scroll data-m-infinite-scroll-root="#feed-js" data-m-infinite-scroll-end="You are all caught up"><span class="spinner spinner-sm"></span>Loading more posts</div>
</div>JavaScript API
Attribute
data-m-infinite-scroll
Options
| Option | Description |
|---|---|
data-m-infinite-scroll-margin="300px" | |
data-m-infinite-scroll-root="#feed" | |
data-m-infinite-scroll-end="You are all caught up" |
Methods
| Method | Description |
|---|---|
Monsoon.infiniteScroll(el).page | |
Monsoon.infiniteScroll(el).reset() |
Events
| Event | Description |
|---|---|
monsoon:load { page, done(more = true) } |
Classes
2 classes. Click a name to copy it. Utilities on the same element always win over component defaults, so any of them can be adjusted with plain utility classes.
| Class | Type | What it does |
|---|---|---|
| Base | Base class of the infinite scroll. On a <div> in the example. Sets flex display, alignment, gap, height, padding and text size.CSS |
|
| Part | Part of the infinite scroll. On a <span> in the example. Sets inline-block display, alignment, width, corner radius, text color and background, and --tone, --spinner-size and --spinner-stroke.CSS |
Usage
The styles ship inside the same stylesheet as the utilities, and the behavior comes from the optional monsoon.js script, which enhances any element with a matching data-m attribute, including markup added later.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/monsooncss">
<script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script>
<!-- Infinite scroll: start from the base class, then add modifiers -->
<div id="feed-js" class="max-h-64 overflow-y-auto rounded-xl border p-3 grid gap-2 max-w-sm">
<article class="rounded-lg border bg-surface p-3 text-sm">Post 1</article>
<article class="rounded-lg border bg-surface p-3 text-sm">Post 2</article>
<article class="rounded-lg border bg-surface p-3 text-sm">Post 3</article>
<article class="rounded-lg border bg-surface p-3 text-sm">Post 4</article>
<div class="infinite-scroll" data-m-infinite-scroll data-m-infinite-scroll-root="#feed-js" data-m-infinite-scroll-end="You are all caught up"><span class="spinner spinner-sm"></span>Loading more posts</div>
</div>Theme it with --seed on any ancestor, for example style="--seed: #0d9488", and force a scheme with class="dark" or class="light" on a wrapper.
Accessibility
- Animations stop under
prefers-reduced-motion: reduce. Mark busy regions witharia-busy="true"and give spinners an accessible name. - Every interactive part shows a visible focus ring with
:focus-visible, and tone colors pair with-foregroundtokens that keep text at 4.5:1 or better in light and dark mode.