Skip to content

Column Pinning

Enterprise

Column pinning freezes one or more columns against the left or right edge of the grid so they stay visible while the remaining columns scroll horizontally. It’s ideal for keeping an identifier (a name or ID) on the left and a status or actions column on the right, no matter how wide the table gets.

Pinning is an enterprise feature. Turn it on by setting the grid’s colPinProvider to columnPinning() and marking columns with pinned:

import { columnPinning } from '@zengrid/enterprise';
const grid = new Zengrid(el, {
colPinProvider: columnPinning(),
columns: [
{ field: 'name', header: 'Name', pinned: 'left' },
{ field: 'role', header: 'Role' },
{ field: 'status', header: 'Status', pinned: 'right' },
],
});

The provider is what reads pinned; without it the marker does nothing. Frozen columns are drawn above the scrolling body and header — both stay aligned as you scroll — with a soft shadow marking each band’s edge.

Because the grid renders individually pooled, absolutely-positioned cells (that is what keeps 100k rows smooth), a frozen column isn’t a separate DOM table — each of its cells is repositioned to scrollLeft + band offset every frame, so it appears to stay put while everything else moves. Left-pinned columns stack from the left edge; right-pinned columns anchor to the right edge in display order.

For pins the user can toggle, drive the provider with a ColumnPinManager instead of (or on top of) the declarative markers. Its pins win over any pinned on the column, and changes apply instantly:

import { columnPinning, ColumnPinManager } from '@zengrid/enterprise';
const pins = new ColumnPinManager();
const grid = new Zengrid(el, { colPinProvider: columnPinning(pins), columns });
pins.pin('name', 'left'); // freeze
pins.toggle('name', 'left'); // …and release (same side toggles off)
pins.unpin('name');
pins.clear(); // release everything

Each tab freezes different columns. Scroll the grid sideways to see the frozen columns hold their place; the last tab pins live from the buttons.

pinned:'left' freezes a column against the left edge. Scroll sideways — Name stays while the rest slide under it. Try pinning Role too.