Dynamic item heights
When rows have different heights, set [dynamicItemHeight]="true". itemHeight then becomes the estimate for rows that have not been rendered yet.
How it works
- Rendered rows are measured with a
ResizeObserver. If a row's content changes height later, the list updates. - Heights are cached by item ID in each list, so they survive reordering. An item moved into another list is measured again there, starting from that list's estimate.
- Offsets are kept as prefix sums, so finding the row at a scroll position is a binary search (O(log n)). A measured height only invalidates the offsets after its row, and they are recomputed only as far as a lookup reaches, so measuring rows while scrolling a long list stays cheap.
dynamicItemHeightanditemHeightcan change at runtime. The list then starts again from the estimate and measures the rendered rows anew. TurningdynamicItemHeightoff stops measuring.
Two rules from Core concepts matter most here. The draggable ID must equal the item ID, and vdndDraggable must be on the template's root element. The list uses both to find the element it measures.
Choosing the estimate
Pick an estimate close to your typical row height. A poor estimate still works, but the scrollbar size and position shift more as rows are measured.
Other components
The same input exists on every virtual container:
Inside <vdnd-virtual-content> or <vdnd-virtual-viewport>, *vdndVirtualFor inherits itemHeight and dynamicItemHeight from its parent. Directly inside a vdndScrollable, it positions each row absolutely at its measured offset (see VirtualForDirective).