# Row height & grid size

> Set the row height for the density you want, give rows their own heights, and size the grid in pixels or to fill its container.

Rows are 36 px tall by default. `rowHeight` sets another height for every row, or a height per row. The grid's own size comes from `height`: a number of pixels for the scrolling area, or a CSS length that sizes the whole grid to fit its container.

Switch between the three densities; the grid keeps scrolling smoothly at each:

Example: Compact, default and roomy rows (row-height.svelte)

```svelte
<script lang="ts">
  import { Grid, type ColumnDef } from 'bo-grid';
  import { quotes } from './data';

  const columns: ColumnDef[] = [
    { type: 'text', key: 'symbol', header: 'Symbol', sub: 'name', width: 170 },
    { type: 'price', key: 'price', header: 'Price', width: 96 },
    { type: 'percent', key: 'change', header: 'Chg %', width: 90 },
    { type: 'volume', key: 'volume', header: 'Volume', flex: 1 },
  ];
  const densities = { Compact: 28, Default: 36, Roomy: 48 };

  let rows = $state(quotes());
  let rowHeight = $state(36);
</script>

<div class="bar" role="group" aria-label="Row height">
  {#each Object.entries(densities) as [label, h] (label)}
    <button aria-pressed={rowHeight === h} onclick={() => (rowHeight = h)}>{label} · {h}px</button>
  {/each}
</div>
<Grid {rows} {columns} {rowHeight} height={260} />

<style>
  .bar {
    display: flex;
    gap: 6px;
    margin-bottom: 10px;
  }
  button {
    padding: 4px 10px;
    font: inherit;
    font-size: 12.5px;
    color: inherit;
    background: none;
    border: 1px solid color-mix(in srgb, currentColor 25%, transparent);
    border-radius: 6px;
    cursor: pointer;
  }
  button[aria-pressed='true'] {
    border-color: currentColor;
  }
</style>
```

data.ts:

```ts
// Small, fixed data for the docs' examples: every example reads the same
// symbols, so a reader compares features, not datasets.
// A type, not an interface: it then fits GridRow's index signature.
export type Quote = {
  id: number;
  symbol: string;
  name: string;
  sector: string;
  price: number;
  change: number;
  volume: number;
};

const BASE: Omit<Quote, 'id'>[] = [
  { symbol: 'VNM', name: 'Vinamilk', sector: 'Consumer', price: 68.5, change: 1.2, volume: 1_204_000 },
  { symbol: 'FPT', name: 'FPT Corp', sector: 'Technology', price: 132, change: -0.4, volume: 860_500 },
  { symbol: 'HPG', name: 'Hoa Phat', sector: 'Materials', price: 27.35, change: 0.74, volume: 3_412_900 },
  { symbol: 'VCB', name: 'Vietcombank', sector: 'Financials', price: 91.5, change: 0.55, volume: 1_986_200 },
  { symbol: 'MWG', name: 'Mobile World', sector: 'Consumer', price: 51.4, change: -1.1, volume: 2_250_400 },
  { symbol: 'SSI', name: 'SSI Securities', sector: 'Financials', price: 33.3, change: -0.45, volume: 4_104_700 },
  { symbol: 'VIC', name: 'Vingroup', sector: 'Real estate', price: 44.15, change: -0.11, volume: 1_530_100 },
  { symbol: 'GAS', name: 'PV Gas', sector: 'Energy', price: 71.8, change: 0.3, volume: 645_800 },
  { symbol: 'MSN', name: 'Masan', sector: 'Consumer', price: 76.2, change: 2.05, volume: 1_120_300 },
  { symbol: 'TCB', name: 'Techcombank', sector: 'Financials', price: 23.9, change: 0.84, volume: 5_870_000 },
  { symbol: 'VHM', name: 'Vinhomes', sector: 'Real estate', price: 41.6, change: -0.72, volume: 2_904_600 },
  { symbol: 'POW', name: 'PV Power', sector: 'Energy', price: 12.25, change: 1.66, volume: 6_315_200 },
];

/** A fresh copy of the quotes, so one example's edits never reach another. */
export function quotes(): Quote[] {
  return BASE.map((q, i) => ({ id: i + 1, ...q }));
}
```

## One height for every row

```svelte
<Grid {rows} {columns} rowHeight={28} height={480} />
```

For a fully compact or roomy look, pair `rowHeight` with the theme's `cellPad` (horizontal padding) and `fontSize`; see [Theming](https://bonguynvan.github.io/bo-grid/docs/theming/).

## A height per row

Pass a function of the row and its index, for rows that need more room, such as a wrapped note:

```svelte
<Grid {rows} {columns} rowHeight={(row, i) => (row.note ? 72 : 36)} height={480} />
```

Variable heights are virtualized with a prefix sum and a binary search, so scrolling stays fast with many rows. They need the rows in memory: with a server [data source](https://bonguynvan.github.io/bo-grid/docs/server-data/), rows not yet loaded have no known height, so source mode uses one height.

Text only wraps in columns that ask for it with `wrap: true` (see [Custom cells](https://bonguynvan.github.io/bo-grid/docs/custom-cells/#tooltips-and-truncation)).

## Sizing the grid

`height` takes a number or a CSS length:

- **A number** is the height of the scrolling area in pixels. The grid's full height is that plus its header, and any toolbar, pager or footer.
- **A CSS string** (`'100%'`, `'80vh'`, `'480px'`) sizes the whole grid, and the scrolling area fits the space left after its header and other parts. Give the grid a parent with a size, such as a flex or grid cell, for `'100%'` to fill.

```svelte
<Grid {rows} {columns} height={640} />  <!-- a 640 px scrolling area -->
<Grid {rows} {columns} height="100%" /> <!-- fill a sized parent -->
<Grid {rows} {columns} height="80vh" />
```

## Reference

- `rowHeight`: `number | ((row: GridRow, index: number) => number)` (default `36`) — Row height in px (uniform), or a function for variable heights (in-memory mode only).

  ```svelte
  <Grid {rows} {columns} height={480} rowHeight={(row) => (row.note ? 56 : 36)} />
  ```

- `height`: `number | string` — Viewport height. A **number** is the scroll viewport's pixel height (the grid's total height is that plus header/toolbar/footer chrome). A **CSS string** (e.g. `'100%'`, `'80vh'`, `'480px'`) sizes the whole grid element and the viewport auto-fits the space left after the chrome — give the grid a sized parent (or use `'100%'` inside a flex/grid cell).

  ```svelte
  <Grid {rows} {columns} height="100%" />
  ```

- `detailHeight`: `number` (default `160`) — Height (px) of the expanded detail panel.

- `wrap`: `boolean` (default `false`) — Let long content wrap to multiple lines instead of truncating with an ellipsis. Pair with a taller `rowHeight`.

---
Page: https://bonguynvan.github.io/bo-grid/docs/row-height/ · All pages: https://bonguynvan.github.io/bo-grid/llms.txt
