Scroll Methods
You can programmatically scroll to any item in the list using the scroll method. This is useful for jump-to-item navigation, search results, and more.
Interactive Demo
Basic Usage
To use the scroll method, bind a reference to the VirtualList component:
<script lang="ts">
import VirtualList from '@humanspeak/svelte-virtual-list'
let listRef
const items = Array.from({ length: 10000 }, (_, i) => ({
id: i,
text: `Item ${i}`
}))
function goToItem5000() {
listRef.scroll({
index: 5000,
smoothScroll: true,
align: 'auto'
})
}
</script>
<button onclick={goToItem5000}>
Scroll to item 5000
</button>
<VirtualList {items} bind:this={listRef}>
{#snippet renderItem(item)}
<div>{item.text}</div>
{/snippet}
</VirtualList><script lang="ts">
import VirtualList from '@humanspeak/svelte-virtual-list'
let listRef
const items = Array.from({ length: 10000 }, (_, i) => ({
id: i,
text: `Item ${i}`
}))
function goToItem5000() {
listRef.scroll({
index: 5000,
smoothScroll: true,
align: 'auto'
})
}
</script>
<button onclick={goToItem5000}>
Scroll to item 5000
</button>
<VirtualList {items} bind:this={listRef}>
{#snippet renderItem(item)}
<div>{item.text}</div>
{/snippet}
</VirtualList>API Reference
scroll(options)
Scrolls the list to bring a specific item into view.
scroll(options: {
index: number
smoothScroll?: boolean
shouldThrowOnBounds?: boolean
align?: 'auto' | 'top' | 'bottom' | 'nearest' | 'center'
}): Promise<void>scroll(options: {
index: number
smoothScroll?: boolean
shouldThrowOnBounds?: boolean
align?: 'auto' | 'top' | 'bottom' | 'nearest' | 'center'
}): Promise<void>Options
| Option | Type | Default | Description |
|---|---|---|---|
index | number | Required | The item index to scroll to (0-based) |
smoothScroll | boolean | true | Use smooth scrolling animation |
shouldThrowOnBounds | boolean | true | Throw error if index is out of bounds |
align | string | 'auto' | Where to align the item in the viewport |
Alignment Options
'auto'(default) - Only scroll if the item is not visible. Aligns to top or bottom as appropriate.'top'- Always align the item to the top of the viewport.'bottom'- Always align the item to the bottom of the viewport.'nearest'- Scroll as little as possible to bring the item into view (like nativescrollIntoView({ block: 'nearest' })).'center'- Center the item vertically in the viewport, clamped at the list edges. Great for focusing a search result or highlighted item so it lands in the middle of the view.
Examples
Scroll to specific index
<button onclick={() => listRef.scroll({ index: 500 })}>
Go to item 500
</button><button onclick={() => listRef.scroll({ index: 500 })}>
Go to item 500
</button>Scroll without animation
<button onclick={() => listRef.scroll({ index: 500, smoothScroll: false })}>
Jump to item 500 (instant)
</button><button onclick={() => listRef.scroll({ index: 500, smoothScroll: false })}>
Jump to item 500 (instant)
</button>Always align to top
<button onclick={() => listRef.scroll({ index: 500, align: 'top' })}>
Scroll to item 500 (top aligned)
</button><button onclick={() => listRef.scroll({ index: 500, align: 'top' })}>
Scroll to item 500 (top aligned)
</button>Minimal scrolling
<button onclick={() => listRef.scroll({ index: 500, align: 'nearest' })}>
Scroll to item 500 (nearest)
</button><button onclick={() => listRef.scroll({ index: 500, align: 'nearest' })}>
Scroll to item 500 (nearest)
</button>Center the item in the viewport
<button onclick={() => listRef.scroll({ index: 500, align: 'center' })}>
Scroll to item 500 (centered)
</button><button onclick={() => listRef.scroll({ index: 500, align: 'center' })}>
Scroll to item 500 (centered)
</button>scrollToOffset(options)
Scrolls the viewport to a raw pixel offset instead of an item index. This complements scroll() (which is index-based) and is ideal for restoring a persisted scroll position after navigation.
scrollToOffset(options: {
offset: number
smoothScroll?: boolean
}): Promise<void>scrollToOffset(options: {
offset: number
smoothScroll?: boolean
}): Promise<void>Offsets address the entire physical content from zero, including measured header and
footer snippets. In horizontal mode this is the leading-edge offset. Index alignment
uses the row coordinate after the header: aligning the final row to end excludes
the footer, while a sufficiently large raw offset or the End key reaches the footer’s
physical end.
The offset is clamped to the list’s valid scroll range, so values beyond the end simply settle at the bottom. The returned promise resolves once scrolling has visually finished.
Options
| Option | Type | Default | Description |
|---|---|---|---|
offset | number | Required | Raw vertical scroll offset in pixels |
smoothScroll | boolean | true | Use smooth scrolling animation |
Example
<script lang="ts">
import VirtualList from '@humanspeak/svelte-virtual-list'
let listRef
// e.g. a value read back from sessionStorage
const savedOffset = 12345
function restoreScrollPosition() {
listRef.scrollToOffset({ offset: savedOffset, smoothScroll: false })
}
</script>
<button onclick={restoreScrollPosition}>
Restore scroll position
</button>
<VirtualList {items} bind:this={listRef}>
{#snippet renderItem(item)}
<div>{item.text}</div>
{/snippet}
</VirtualList><script lang="ts">
import VirtualList from '@humanspeak/svelte-virtual-list'
let listRef
// e.g. a value read back from sessionStorage
const savedOffset = 12345
function restoreScrollPosition() {
listRef.scrollToOffset({ offset: savedOffset, smoothScroll: false })
}
</script>
<button onclick={restoreScrollPosition}>
Restore scroll position
</button>
<VirtualList {items} bind:this={listRef}>
{#snippet renderItem(item)}
<div>{item.text}</div>
{/snippet}
</VirtualList>TypeScript
For full type safety, you can type the ref:
type ListRef = {
scroll: (options: {
index: number
smoothScroll?: boolean
shouldThrowOnBounds?: boolean
align?: 'auto' | 'top' | 'bottom' | 'nearest' | 'center'
}) => Promise<void>
scrollToOffset: (options: {
offset: number
smoothScroll?: boolean
}) => Promise<void>
}
let listRef: ListRef | undefined = $state(undefined)type ListRef = {
scroll: (options: {
index: number
smoothScroll?: boolean
shouldThrowOnBounds?: boolean
align?: 'auto' | 'top' | 'bottom' | 'nearest' | 'center'
}) => Promise<void>
scrollToOffset: (options: {
offset: number
smoothScroll?: boolean
}) => Promise<void>
}
let listRef: ListRef | undefined = $state(undefined)Or import the types from the package:
import type {
SvelteVirtualListScrollOptions,
SvelteVirtualListScrollAlign
} from '@humanspeak/svelte-virtual-list'import type {
SvelteVirtualListScrollOptions,
SvelteVirtualListScrollAlign
} from '@humanspeak/svelte-virtual-list'