Step one
A demo, in Rust
Interactivity is a CSS feature now.
Five pages of menus, modals, tabs, tooltips, sorting and validation. Rendered by axum and maud, styled with Tailwind, and shipped with exactly zero bytes of JavaScript — no script tags, no hydration, no bundle.
Navigate between pages
@view-transitionDeclaring @view-transition { navigation: auto } opts the whole document into cross-document view transitions, so the browser cross-fades between two server-rendered pages instead of flashing white.
Step two
Server renders
Step three
Browser cross-fades
view-transition-name, so it stays put while the body fades.view-transition-nameThe sticky header is given a stable transition name, which makes the browser treat it as the same element across the navigation rather than fading it out and back in.
Reveal on scroll
animation-timeline: view()Each section runs a fade-and-rise keyframe animation whose timeline is its own position in the viewport, so progress is driven by scrolling rather than by a script watching an IntersectionObserver.
The sidebar on the interactive page is a checkbox plus body:has(#toggle:checked).
The dropdown and the modal are the popover attribute, styled with :popover-open.
The data table sorts and filters in Rust, driven entirely by query parameters.
The form validates server-side and renders its own errors back into the markup.
animation-range: entryThe animation range is pinned to the element's entry into the scrollport, so each row finishes its reveal shortly after it clears the bottom edge.
Reading progress
animation-timeline: scroll(root)The bar at the top of this page scales along the X axis with a scroll-progress timeline attached to the document's scroll container — no scroll listener, no layout thrash.
Graceful degradation
Everything here is progressive
@view-transition just navigate normally. Nothing depends on the effect firing.Motion safety