Autosize columns
api.autosizeColumn(id) and api.autosizeAllColumns() snap columns to the widest visible cell via canvas-based text measurement. The column header menu has an "Autosize" item that calls the same code. Manual drag-resize still works.
A live, editable Svelte 5 data grid example from the SvGrid gallery (Columns). See the SvGrid documentation for the full API.
About this example
Column autosize in the Svelte 5 data grid. Every header menu has an Autosize item, and api.autosizeColumn(id) and api.autosizeAllColumns() do the same from code: both walk the rendered cells of the column, measure the widest text on a canvas and snap the width to fit. Manual drag-resize with columnResize keeps working alongside it.
The grid ships built-in autosize: every column's header menu has an "Autosize" item, and api.autosizeColumn(id) / api.autosizeAllColumns() drive it programmatically. Both walk the rendered cells in the column, measure the widest text via canvas, and snap the column width to fit.
Try it: open any column's header menu (the 3-dot button) and pick "Autosize". Or hit the "Autosize every column" button below.
Imports, features and API used
Imports: @svgrid/grid
Table features registered: rowSortingFeature, columnFilteringFeature
Columns: sku (SKU), product (Product), vendor (Vendor), tags (Tags), price (Price)
SvGridApi methods called: api.autosizeAllColumns(), api.autosizeColumn()
Frequently asked questions
How do I size all columns to their content?
Call api.autosizeAllColumns() once the API is ready, or per column with api.autosizeColumn('product'). Users get the same action from the Autosize item in each header menu.
How is the width measured?
The text of each rendered cell in the column is measured with canvas text measurement in the grid's font, and the column takes the widest value plus padding, so the result reflects the visible content.
Can I still resize by hand afterwards?
Yes. columnResize stays on; dragging a header edge overrides the autosized width, and double-clicking the edge autosizes again.
Related documentation
Related articles
- Multi-Level (Grouped) Column Headers in SvGrid - Band related columns under a shared parent header using SvGrid's nested column definition - how to nest, pin, combine with sorting and filtering, and when NOT to use grouping.
- A Custom Column Header Menu in SvGrid - Build a per-column header menu for sort, hide, pin, and custom actions using header snippets and your own dropdown component.
- A Column Show/Hide Toggle in SvGrid - Build a column chooser panel that lets users show or hide columns at runtime, with persistence across page loads and a guard against hiding everything.
Source code (172-autosize-columns.svelte)
<script lang="ts">
/**
* 172. Autosize columns
* ----------------------
* The grid ships built-in autosize: every column's header menu has an
* "Autosize" item, and `api.autosizeColumn(id)` /
* `api.autosizeAllColumns()` drive it programmatically. Both walk the
* rendered cells in the column, measure the widest text via canvas,
* and snap the column width to fit.
*
* Try it: open any column's header menu (the 3-dot button) and pick
* "Autosize". Or hit the "Autosize every column" button below.
*/
import {
SvGrid,
tableFeatures,
rowSortingFeature,
columnFilteringFeature,
type GridColumns,
type SvGridApi,
} from '@svgrid/grid'
type Row = { sku: string; product: string; vendor: string; tags: string; price: number }
const PRODUCTS = [
'Industrial-grade CNC titanium hex bolt M8x40 (graded 12.9)',
'Stainless steel ball bearing 6203-2RS (sealed)',
'High-torque servo driver MX-28T 12V',
'Composite carbon-fiber side panel, glossy black, 240x180mm',
'Precision optical encoder 2048 PPR with index pulse',
'Aluminum heat sink 60x40x20 with thermal interface pad',
'Linear actuator 200mm stroke, 12V, 100N rated load',
'Brushless DC motor 24V 200W with Hall sensors',
]
const VENDORS = [
'Northwind Industrial',
'Pacific Components',
'Cascade Robotics & Motion',
'Vanguard Materials Group',
'Helios Sensor Systems',
'Polaris Precision Tools',
]
const TAGS = [
'in-stock · ROHS',
'lead-time 2w',
'preferred vendor · ISO 9001',
'limited stock',
'discontinued (substitute available)',
]
let rows = $state<Row[]>(Array.from({ length: 40 }, (_, i) => ({
sku: `SKU-${10_000 + i}`,
product: PRODUCTS[i % PRODUCTS.length]!,
vendor: VENDORS[i % VENDORS.length]!,
tags: TAGS[i % TAGS.length]!,
price: Math.round(20 + ((i * 173) % 800)),
})))
const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })
// Start with cramped widths so the demo of autosize is obvious.
const columns: GridColumns<Row> = [
{ field: 'sku', header: 'SKU', width: 90, editorType: 'text' },
{ field: 'product', header: 'Product', width: 110, editorType: 'text' },
{ field: 'vendor', header: 'Vendor', width: 110, editorType: 'list', editorOptions: VENDORS },
{ field: 'tags', header: 'Tags', width: 110, editorType: 'list', editorOptions: TAGS },
{ field: 'price', header: 'Price', width: 90, align: 'right', editorType: 'number',
format: { type: 'currency', currency: 'USD', options: { maximumFractionDigits: 0 } } },
]
let api = $state<SvGridApi<typeof features, Row> | null>(null)
function autosizeAll() {
api?.autosizeAllColumns()
}
</script>
<section class="flex flex-col flex-1 min-h-0 gap-3">
<header>
<h2 class="text-base font-semibold">Autosize columns</h2>
<p class="text-xs mt-1" style="color: var(--sg-muted);">
Open the 3-dot header menu on any column and pick <em>Autosize</em>, or hit the button
below to run <code>api.autosizeAllColumns()</code>. The grid walks the rendered cells,
canvas-measures the widest text, and snaps the column to fit. Drag still resizes manually.
</p>
<div class="mt-2">
<button class="az-btn" onclick={autosizeAll}>Autosize every column</button>
</div>
</header>
<div class="az-wrap">
<SvGrid responsive={true}
columnResize
data={rows}
columns={columns}
features={features}
sortable
filterable
selectionMode="cell"
showRowSelection={false}
showColumnFilters={false}
enableInlineEditing={true}
enableCellSelection={true}
rowHeight={30}
containerHeight="100%"
fitColumns={false}
onApiReady={(next) => (api = next)}
/>
</div>
</section>
<style>
.az-wrap {
flex: 1; min-height: 0;
border: 1px solid var(--sg-border, #e2e8f0);
border-radius: 8px;
overflow: hidden;
}
.az-btn {
border: 1px solid var(--sg-border, #cbd5e1);
background: var(--sg-accent, #2563eb);
color: var(--sg-on-accent, white);
padding: 5px 12px;
border-radius: 6px;
font-size: 12px;
font-weight: 600;
cursor: pointer;
}
.az-btn:hover { filter: brightness(1.08); }
</style>More Columns examples
- Column pinning + freezing - Wide 13-column grid. Pin Company left and Price right via the column menu; the middle scrolls under sticky edges.
- Columns hierarchy + manager - Side-panel tree of grouped columns: drag leaves to reorder, click a chevron to collapse a group into one summary column, toggle visibility per leaf or whole group.
- Column layout API - setColumnWidth + setColumnPinning + getColumnWidths + getColumnPinning. Save the snapshot to localStorage, restore on reload, drive widths and pins from buttons.
- Tool panel (Columns + Filters) - The docked enterprise sidebar, two tabs. Columns: toggle visibility, reorder up/down, group by a column. Filters: an operator + value control per column (numeric operators come free via cellDataType), kept in sync with the column menu. Enable with the toolPanel prop.
- Column reorder - Set enableColumnReorder on <SvGrid> and every header becomes draggable, with a drop indicator. api.setColumnOrder / getColumnOrder + onColumnOrderChange event; persist to restore across reloads.