Skip to content
← Page Transition
Edit Page Transition
Name
Also known as (comma separated)
Brief definition
Animated change between pages/views.
Notes
Tier
Core
Useful
Reference
Deleted
Controls schema (JSON array)
[ { "id": "style", "type": "select", "label": "Transition style", "default": "fade", "options": [ "fade", "slide", "scale" ] }, { "id": "duration", "type": "number", "label": "Duration (ms)", "default": 900, "min": 200, "max": 2000, "step": 100 }, { "id": "loop", "type": "toggle", "label": "Auto-cycle pages", "default": true }, { "id": "accent", "type": "color", "label": "Colour", "default": "#BFD9F2", "presets": [ "#A8E6C1", "#F5C2E0", "#BFD9F2", "#D9C8F0", "#E8A020", "#241430" ] } ]
Templates (JSON object keyed by format)
{ "html": "<div class=\"mot-pgt-stage\" data-style=\"{{style}}\">\n <div class=\"mot-pgt-page mot-pgt-page--a{{#if loop}} mot-pgt-page--cycle{{/if}}\" style=\"background:{{accent}};\">Page A</div>\n <div class=\"mot-pgt-page mot-pgt-page--b{{#if loop}} mot-pgt-page--cycle{{/if}}\">Page B</div>\n <p class=\"mot-pgt-caption\">{{style}} transition · {{duration}}ms between routes</p>\n</div>\n<style>\n.mot-pgt-stage { position: relative; width: 100%; max-width: 320px; height: 100px; background: #FAF7F2; border: 1px solid #24143022; border-radius: 12px; overflow: hidden; font: 13px system-ui, sans-serif; color: #241430aa; }\n.mot-pgt-page { position: absolute; inset: 0; display: grid; place-items: center; font-weight: 700; color: #241430; }\n.mot-pgt-page--b { background: #FAF7F2; border: 2px dashed #24143033; opacity: 0; }\n.mot-pgt-caption { position: absolute; bottom: -26px; left: 0; }\n@media (prefers-reduced-motion: no-preference) {\n [data-style=\"fade\"] .mot-pgt-page--cycle.mot-pgt-page--a { animation: mot-pgt-fade-out {{duration}}ms ease-in-out infinite; }\n [data-style=\"fade\"] .mot-pgt-page--cycle.mot-pgt-page--b { animation: mot-pgt-fade-in {{duration}}ms ease-in-out infinite; }\n [data-style=\"slide\"] .mot-pgt-page--cycle.mot-pgt-page--a { animation: mot-pgt-slide-out {{duration}}ms ease-in-out infinite; }\n [data-style=\"slide\"] .mot-pgt-page--cycle.mot-pgt-page--b { animation: mot-pgt-slide-in {{duration}}ms ease-in-out infinite; }\n [data-style=\"scale\"] .mot-pgt-page--cycle.mot-pgt-page--a { animation: mot-pgt-scale-out {{duration}}ms ease-in-out infinite; }\n [data-style=\"scale\"] .mot-pgt-page--cycle.mot-pgt-page--b { animation: mot-pgt-scale-in {{duration}}ms ease-in-out infinite; }\n @keyframes mot-pgt-fade-out { 0%,45% { opacity: 1; } 50%,100% { opacity: 0; } }\n @keyframes mot-pgt-fade-in { 0%,45% { opacity: 0; } 50%,95% { opacity: 1; } 100% { opacity: 0; } }\n @keyframes mot-pgt-slide-out { 0%,45% { transform: translateX(0); } 50%,100% { transform: translateX(-100%); } }\n @keyframes mot-pgt-slide-in { 0%,45% { transform: translateX(100%); opacity: 1; } 50%,95% { transform: translateX(0); opacity: 1; } 100% { transform: translateX(100%); } }\n @keyframes mot-pgt-scale-out { 0%,45% { opacity: 1; transform: scale(1); } 50%,100% { opacity: 0; transform: scale(1.15); } }\n @keyframes mot-pgt-scale-in { 0%,45% { opacity: 0; transform: scale(.85); } 50%,95% { opacity: 1; transform: scale(1); } 100% { opacity: 0; } }\n}\n</style>", "tailwind": "<div class=\"relative w-full max-w-[320px] h-[100px] bg-[#FAF7F2] border border-[#24143022] rounded-xl overflow-hidden font-sans text-sm text-[#241430]/70\" data-style=\"{{style}}\">\n <div class=\"tw-pgt-a{{#if loop}} tw-pgt-cycle{{/if}} absolute inset-0 grid place-items-center font-bold text-[#241430]\" style=\"background:{{accent}};\">Page A</div>\n <div class=\"tw-pgt-b{{#if loop}} tw-pgt-cycle{{/if}} absolute inset-0 grid place-items-center font-bold text-[#241430] bg-[#FAF7F2] border-2 border-dashed border-[#24143033] opacity-0\">Page B</div>\n <p class=\"absolute -bottom-6 left-0\">{{style}} transition · {{duration}}ms between routes</p>\n</div>\n<style>\n@media (prefers-reduced-motion: no-preference) {\n [data-style=\"fade\"] .tw-pgt-cycle.tw-pgt-a { animation: mot-pgt-tw-fade-out {{duration}}ms ease-in-out infinite; }\n [data-style=\"fade\"] .tw-pgt-cycle.tw-pgt-b { animation: mot-pgt-tw-fade-in {{duration}}ms ease-in-out infinite; }\n [data-style=\"slide\"] .tw-pgt-cycle.tw-pgt-a { animation: mot-pgt-tw-slide-out {{duration}}ms ease-in-out infinite; }\n [data-style=\"slide\"] .tw-pgt-cycle.tw-pgt-b { animation: mot-pgt-tw-slide-in {{duration}}ms ease-in-out infinite; }\n [data-style=\"scale\"] .tw-pgt-cycle.tw-pgt-a { animation: mot-pgt-tw-scale-out {{duration}}ms ease-in-out infinite; }\n [data-style=\"scale\"] .tw-pgt-cycle.tw-pgt-b { animation: mot-pgt-tw-scale-in {{duration}}ms ease-in-out infinite; }\n @keyframes mot-pgt-tw-fade-out { 0%,45% { opacity: 1; } 50%,100% { opacity: 0; } }\n @keyframes mot-pgt-tw-fade-in { 0%,45% { opacity: 0; } 50%,95% { opacity: 1; } 100% { opacity: 0; } }\n @keyframes mot-pgt-tw-slide-out { 0%,45% { transform: translateX(0); } 50%,100% { transform: translateX(-100%); } }\n @keyframes mot-pgt-tw-slide-in { 0%,45% { transform: translateX(100%); opacity: 1; } 50%,95% { transform: translateX(0); opacity: 1; } 100% { transform: translateX(100%); } }\n @keyframes mot-pgt-tw-scale-out { 0%,45% { opacity: 1; transform: scale(1); } 50%,100% { opacity: 0; transform: scale(1.15); } }\n @keyframes mot-pgt-tw-scale-in { 0%,45% { opacity: 0; transform: scale(.85); } 50%,95% { opacity: 1; transform: scale(1); } 100% { opacity: 0; } }\n}\n</style>", "react": "export function PageTransition({\n style = \"{{style}}\",\n duration = {{duration}},\n loop = {{loop}},\n accent = \"{{accent}}\",\n}) {\n const cls = loop ? \"cycle\" : \"\";\n return (\n <div style={{ position: \"relative\", width: \"100%\", maxWidth: 320, height: 100, background: \"#FAF7F2\", border: \"1px solid #24143022\", borderRadius: 12, overflow: \"hidden\", fontFamily: \"system-ui, sans-serif\", fontSize: 13, color: \"#241430aa\" }}>\n <div className={`page-a ${cls}`} style={{ position: \"absolute\", inset: 0, display: \"grid\", placeItems: \"center\", fontWeight: 700, color: \"#241430\", background: accent }}>Page A</div>\n <div className={`page-b ${cls}`} style={{ position: \"absolute\", inset: 0, display: \"grid\", placeItems: \"center\", fontWeight: 700, color: \"#241430\", background: \"#FAF7F2\", border: \"2px dashed #24143033\", opacity: 0 }}>Page B</div>\n <p style={{ position: \"absolute\", bottom: -26, left: 0 }}>{style} transition · {duration}ms between routes</p>\n <style>{`\n @media (prefers-reduced-motion: no-preference) {\n [data-style=\"fade\"] .page-a.cycle, .fade-a { animation: mot-pgt-fade-out ${duration}ms ease-in-out infinite; }\n .page-a.cycle { animation: ${style === \"fade\" ? \"mot-pgt-fade-out\" : style === \"slide\" ? \"mot-pgt-slide-out\" : \"mot-pgt-scale-out\"} ${duration}ms ease-in-out infinite; }\n .page-b.cycle { animation: ${style === \"fade\" ? \"mot-pgt-fade-in\" : style === \"slide\" ? \"mot-pgt-slide-in\" : \"mot-pgt-scale-in\"} ${duration}ms ease-in-out infinite; }\n @keyframes mot-pgt-fade-out { 0%,45% { opacity: 1; } 50%,100% { opacity: 0; } }\n @keyframes mot-pgt-fade-in { 0%,45% { opacity: 0; } 50%,95% { opacity: 1; } 100% { opacity: 0; } }\n @keyframes mot-pgt-slide-out { 0%,45% { transform: translateX(0); } 50%,100% { transform: translateX(-100%); } }\n @keyframes mot-pgt-slide-in { 0%,45% { transform: translateX(100%); opacity: 1; } 50%,95% { transform: translateX(0); opacity: 1; } 100% { transform: translateX(100%); } }\n @keyframes mot-pgt-scale-out { 0%,45% { opacity: 1; transform: scale(1); } 50%,100% { opacity: 0; transform: scale(1.15); } }\n @keyframes mot-pgt-scale-in { 0%,45% { opacity: 0; transform: scale(.85); } 50%,95% { opacity: 1; transform: scale(1); } 100% { opacity: 0; } }\n }\n `}</style>\n </div>\n );\n}" }
Save
History