demo · v137
SPA List
The exact use case the spec calls out: a list in a single-page app where items get added, deleted, reordered. Without match-element you'd hand-assign view-transition-name: item-42 to every row. With it, the browser stamps a stable identity from the element — so insertions and deletions morph the right pieces and you don't have to think about it.
Heads up
view-transition-name: match-element requires Chrome 137+. The probe below tells you what's wired.probing…
match-element (v137+)
No view-transition-name attribute - one line of CSS: li { view-transition-name: match-element; }
no name (legacy)
Rows have no individual identity - inserts/deletes cross-fade the whole list rather than morphing individual rows.
the code
li { view-transition-name: match-element; }
function withTransition(mutator) {
if (!document.startViewTransition) return mutator();
document.startViewTransition(mutator);
}
addBtn.onclick = () => withTransition(() => {
list.prepend(buildRow("new task #" + (++n)));
});
deleteBtn.onclick = () => withTransition(() => {
pickRandom(list.children).remove();
});