Shared elements
Make an element travel between pages with the mira-morph attribute.
A shared element is the same thing shown on two pages, such as a post title on a list and on the post itself. Give both the same mira-morph name and it moves from one position to the other during the transition.
<!-- routes/posts/index.mira -->
{#each collections.posts as post}
{{ post.title }}
{/each}
<!-- routes/posts/[slug].mira -->
{{ entry.title }}
On this site, each page’s heading carries a name like doc-routing, so a link with the same name morphs into it.
What the compiler does
mira-morph="title-ship-less" becomes data-mira-morph="title-ship-less", and the page’s own stylesheet gets:
}
Names live in the stylesheet rather than in inline style attributes, so pages keep a strict content security policy.
Rules
- Unique per page. A name used twice on one page makes the browser skip the whole transition, so Mira fails the build instead.
- Valid names. Characters other than letters, digits,
-, and_become-. A name starting with a digit gets anm-prefix.none,auto,root, and other CSS keywords are rejected. - Stable elements. An element with the same name and position on both pages, such as a site header, holds still while the rest of the page changes. This site’s docs sidebar uses that to stay put.
Styling the motion
Every shared element carries the view transition class mira-morph, so you can tune them together:
) }
Or one at a time by name:
) }
Tips
- Give shared elements
width: fit-contentwhen the text should not stretch across the column during the move. - Morph the text, not its card. Large boxes changing aspect ratio distort.
- Keep names derived from stable data, such as a slug, rather than a position in a list.