terminalCode Example

VirtualGrid — efficiently rendering large scrollable lists in s&box UI

calendar_today May 5, 2026 schedule ~1 min read person patrickjr verified 50

VirtualGrid — Efficiently Rendering Large Lists in UI

VirtualGrid is a s&box UI panel that virtualizes a large collection — only the visible cells are created in the DOM. Scrolling destroys off-screen cells and creates new ones, keeping memory and layout cost constant regardless of list size.

Basic Usage in Razor

RAZOR
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent

<root>
    <VirtualGrid Items=@Items ItemSize=@(new Vector2(120, 120))>
        <Item Context="item">
            @if ( item is PackageEntry entry )
            {
                <div class="package-card">
                    
                    <label>@entry.Title</label>
                </div>
            }
        </Item>
    </VirtualGrid>
</root>

@code {
    public IEnumerable<PackageEntry> Items { get; set; } = Array.Empty<PackageEntry>();
    protected override int BuildHash() => System.HashCode.Combine( Items );
}

ItemSize

ItemSize is a Vector2. The grid scales cells up so they fit flush in the container while preserving the aspect ratio:
RAZOR
<VirtualGrid Items=@Items ItemSize=@(new Vector2(200, 150))>

Spacing Between Cells

Use CSS gap on the VirtualGrid element:

CSS
.my-grid VirtualGrid {
    gap: 8px;
}

Required: Give VirtualGrid a Size

VirtualGrid must have an explicit size in CSS — it won't size itself:
CSS
.my-grid VirtualGrid {
    width: 100%;
    height: 100%;
}

Updating the List

Assign a new collection to Items and call StateHasChanged() to trigger a rebuild:

CSHARP
protected override void OnUpdate()
{
    var newItems = GetFilteredPackages();
    if ( newItems != Items )
    {
        Items = newItems;
        StateHasChanged();
    }
}

When to Use

  • Package browsers, item shops, inventory grids with hundreds of entries
  • Any scrollable list where creating all DOM nodes at once would be slow
  • All items must be the same size — VirtualGrid doesn't support variable-height rows
Was this helpful?