Grid #
Converts a vertical list into a 2D grid layout.
import { createVList, grid } from "vlist";
const list = createVList({
container: "#app",
item: { height: 120, template: renderCard },
items: data,
}, [grid({ columns: 3, gap: 8 })]);
Config #
| Option | Type | Default | Description |
|---|---|---|---|
columns |
number |
required | Number of columns (>= 1) |
gap |
number |
0 |
Space between cells (px) |
Aspect Ratios #
Use the columnWidth context to create responsive aspect ratios that adapt when the container resizes:
const list = createVList({
container: "#app",
item: {
height: (_index, { columnWidth }) => Math.round(columnWidth * 0.75), // 4:3
template: renderCard,
},
items: photos,
}, [grid({ columns: 3, gap: 8 })]);
Common ratios: * 1 (square), * 0.75 (4:3), * (9/16) (16:9), * (4/3) (3:4 portrait).
Static height: 120 values break aspect ratios on resize — always use the function form for responsive grids.
Responsive Columns #
Update the column count dynamically based on viewport width:
const updateColumns = () => {
const w = window.innerWidth;
const cols = w < 480 ? 2 : w < 768 ? 3 : w < 1200 ? 4 : 5;
list.updateGrid({ columns: cols });
};
window.addEventListener("resize", updateColumns);
Methods #
| Method | Returns | Description |
|---|---|---|
getGridLayout() |
GridLayout |
Grid layout instance (see below) |
updateGrid(config) |
void |
Update columns and/or gap dynamically |
GridLayout properties and methods:
| Member | Type | Description |
|---|---|---|
columns |
number |
Current column count |
gap |
number |
Current gap |
getRow(index) |
number |
Row for item index |
getCol(index) |
number |
Column for item index |
getTotalRows(total) |
number |
Total row count |
getColumnWidth(containerWidth) |
number |
Computed column width |
CSS Classes #
.vlist--gridon root.vlist-grid-itemon items
Large datasets #
Combine with scale for grids with 1M+ items. Compression is handled automatically — range calculation and item positioning switch to viewport-relative mode when the total content height exceeds the browser limit.
const list = createVList({
container: "#app",
item: { height: 120, template: renderCard },
items: millionItems,
}, [grid({ columns: 4, gap: 8 }), scale(), scrollbar()]);
Notes #
- Keyboard nav: arrows move in 2D (left/right between columns, up/down between rows)
- Works with scale plugin for 1M+ item grids
- Conflicts with: masonry, table
Examples #
- Photo Album — responsive gallery with grid and masonry toggle
- Large Dataset — 1M+ items with grid + scale compression
- File Browser — Finder-like grid and table views