Custom Page Transitions with SharedAxisTransition
Oct 15, 2025



Summary
Summary
Summary
Summary
This tutorial explains how to implement custom page routes with SharedAxisTransition from the Flutter animations package, covering axis choices, a reusable PageRouteBuilder helper, navigation examples, performance, and accessibility considerations for polished mobile development.
This tutorial explains how to implement custom page routes with SharedAxisTransition from the Flutter animations package, covering axis choices, a reusable PageRouteBuilder helper, navigation examples, performance, and accessibility considerations for polished mobile development.
This tutorial explains how to implement custom page routes with SharedAxisTransition from the Flutter animations package, covering axis choices, a reusable PageRouteBuilder helper, navigation examples, performance, and accessibility considerations for polished mobile development.
This tutorial explains how to implement custom page routes with SharedAxisTransition from the Flutter animations package, covering axis choices, a reusable PageRouteBuilder helper, navigation examples, performance, and accessibility considerations for polished mobile development.
Key insights:
Key insights:
Key insights:
Key insights:
Understanding SharedAxisTransition: Choose horizontal, vertical, or scaled to convey different spatial or hierarchical relationships.
Setting Up The PageRoute: Encapsulate the SharedAxisTransition in a PageRouteBuilder helper to centralize duration and type settings.
Implementing The Transition: Push the custom route via Navigator.push to preserve secondaryAnimation and animate the outgoing page.
Performance And Design Considerations: Keep durations sensible, respect reduced-motion accessibility, and avoid excessive rebuilds for smooth frames.
Debugging Tips: Use keys to preserve widget identity, confirm the correct Navigator provides secondaryAnimation, and inspect performance overlays.
Introduction
Smooth, context-preserving transitions elevate mobile apps. Flutter's animations package includes SharedAxisTransition, a Material motion pattern that animates two UI elements along a shared axis to emphasize spatial or hierarchical relationships. This tutorial shows how to wire SharedAxisTransition into custom page routes, when to pick axis types, and practical tips for production-ready mobile development.
Understanding SharedAxisTransition
SharedAxisTransition animates incoming and outgoing elements along a common X, Y, or Z axis. Use the axis you want to emphasize:
Horizontal: use for lateral navigation between sibling destinations (tabs, similar pages).
Vertical: use for drill-down/up flows or stacked content.
Scaled (Z): use to de-emphasize hierarchy and suggest a change in visual depth.
SharedAxisTransition composes two animations: a position (translation) and a fade/scale. It helps users maintain context because the movement implies a relation between screens, unlike abrupt switches.
The transition is part of the animations package. Add it to pubspec.yaml:
Add dependency: animations: ^2.0.0 (or latest stable)
Then import:
import 'package:animations/animations.dart';
Setting Up The PageRoute
SharedAxisTransition is used inside a transitionsBuilder, so the most straightforward integration is a custom PageRouteBuilder. Create a helper that returns a route configured with the chosen axis and duration. Keep the code modular so you can re-use the route across pushes.
Example route helper:
PageRouteBuilder<T> sharedAxisRoute<T>(Widget page, SharedAxisTransitionType type) {
return PageRouteBuilder<T>(
transitionDuration: const Duration(milliseconds: 330),
reverseTransitionDuration: const Duration(milliseconds: 300),
pageBuilder: (_, __, ___) => page,
transitionsBuilder: (_, animation, secondaryAnimation, child) {
return SharedAxisTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
transitionType: type,
child: child,
);
},
);
}
This isolates the transition configuration: change durations, curve, or the transitionType (SharedAxisTransitionType.horizontal, .vertical, .scaled) in one place.
Implementing The Transition
Use the route helper when navigating. For push operations, pass the route from Navigator.push. For modal-like flows, prefer Navigator.of(context).push to preserve back behavior and secondaryAnimation support.
Small example of pushing a detail page with a vertical axis:
Navigator.of(context).push(
sharedAxisRoute(DetailPage(), SharedAxisTransitionType.vertical),
);
If you need parameters such as Hero widgets or keyed elements, keep the child consistent and avoid rebuilding the destination widget unnecessarily. SharedAxisTransition uses secondaryAnimation to animate the outgoing page; that keeps the outgoing widget mounted and animated — ideal for maintaining visual continuity.
Performance And Design Considerations
Duration and Curves: The default durations in Material motion are tuned for clarity. 300–360ms is a good range. If you need quicker transitions, reduce duration but test perceived continuity.
Avoid Overuse: Use SharedAxisTransition where the two pages are conceptually related. Overusing motion reduces impact and can slow perceived performance.
Accessibility: Respect platform motion preferences. Check MediaQuery.of(context).disableAnimations (or an equivalent) and fall back to a simple fade or no animation.
Rebuilds: Keep child widgets const where possible. SharedAxisTransition drives animations; excessive rebuilds in the tree can drop frames.
Nested Navigators: If you have nested navigators, ensure the right navigator instance receives the push so the secondaryAnimation is provided. Otherwise you may get a non-animated exit.
Platform Consistency: On iOS, users expect right-to-left back gestures. If you replace default Cupertino transitions, ensure gestures still feel natural or provide an alternative.
Debugging Tips
If you see a flicker or abrupt cut, confirm the outgoing page isn’t being rebuilt to a new identity. Use Keys to maintain identity.
If the outgoing page doesn't animate, verify the Navigator you pushed to provides a secondaryAnimation (root Navigator usually does).
Use the Performance overlay and the Flutter inspector to trace repaint boundaries and locate expensive frames.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
SharedAxisTransition is a concise, powerful tool to communicate relationships between screens in Flutter mobile development. By centralizing route creation, respecting performance and accessibility guidelines, and choosing the appropriate axis, you can add polished, coherent motion to your app without a large code surface. Integrate the animations package, keep transitions consistent, and test on a range of devices to ensure smooth, meaningful navigation.
Introduction
Smooth, context-preserving transitions elevate mobile apps. Flutter's animations package includes SharedAxisTransition, a Material motion pattern that animates two UI elements along a shared axis to emphasize spatial or hierarchical relationships. This tutorial shows how to wire SharedAxisTransition into custom page routes, when to pick axis types, and practical tips for production-ready mobile development.
Understanding SharedAxisTransition
SharedAxisTransition animates incoming and outgoing elements along a common X, Y, or Z axis. Use the axis you want to emphasize:
Horizontal: use for lateral navigation between sibling destinations (tabs, similar pages).
Vertical: use for drill-down/up flows or stacked content.
Scaled (Z): use to de-emphasize hierarchy and suggest a change in visual depth.
SharedAxisTransition composes two animations: a position (translation) and a fade/scale. It helps users maintain context because the movement implies a relation between screens, unlike abrupt switches.
The transition is part of the animations package. Add it to pubspec.yaml:
Add dependency: animations: ^2.0.0 (or latest stable)
Then import:
import 'package:animations/animations.dart';
Setting Up The PageRoute
SharedAxisTransition is used inside a transitionsBuilder, so the most straightforward integration is a custom PageRouteBuilder. Create a helper that returns a route configured with the chosen axis and duration. Keep the code modular so you can re-use the route across pushes.
Example route helper:
PageRouteBuilder<T> sharedAxisRoute<T>(Widget page, SharedAxisTransitionType type) {
return PageRouteBuilder<T>(
transitionDuration: const Duration(milliseconds: 330),
reverseTransitionDuration: const Duration(milliseconds: 300),
pageBuilder: (_, __, ___) => page,
transitionsBuilder: (_, animation, secondaryAnimation, child) {
return SharedAxisTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
transitionType: type,
child: child,
);
},
);
}
This isolates the transition configuration: change durations, curve, or the transitionType (SharedAxisTransitionType.horizontal, .vertical, .scaled) in one place.
Implementing The Transition
Use the route helper when navigating. For push operations, pass the route from Navigator.push. For modal-like flows, prefer Navigator.of(context).push to preserve back behavior and secondaryAnimation support.
Small example of pushing a detail page with a vertical axis:
Navigator.of(context).push(
sharedAxisRoute(DetailPage(), SharedAxisTransitionType.vertical),
);
If you need parameters such as Hero widgets or keyed elements, keep the child consistent and avoid rebuilding the destination widget unnecessarily. SharedAxisTransition uses secondaryAnimation to animate the outgoing page; that keeps the outgoing widget mounted and animated — ideal for maintaining visual continuity.
Performance And Design Considerations
Duration and Curves: The default durations in Material motion are tuned for clarity. 300–360ms is a good range. If you need quicker transitions, reduce duration but test perceived continuity.
Avoid Overuse: Use SharedAxisTransition where the two pages are conceptually related. Overusing motion reduces impact and can slow perceived performance.
Accessibility: Respect platform motion preferences. Check MediaQuery.of(context).disableAnimations (or an equivalent) and fall back to a simple fade or no animation.
Rebuilds: Keep child widgets const where possible. SharedAxisTransition drives animations; excessive rebuilds in the tree can drop frames.
Nested Navigators: If you have nested navigators, ensure the right navigator instance receives the push so the secondaryAnimation is provided. Otherwise you may get a non-animated exit.
Platform Consistency: On iOS, users expect right-to-left back gestures. If you replace default Cupertino transitions, ensure gestures still feel natural or provide an alternative.
Debugging Tips
If you see a flicker or abrupt cut, confirm the outgoing page isn’t being rebuilt to a new identity. Use Keys to maintain identity.
If the outgoing page doesn't animate, verify the Navigator you pushed to provides a secondaryAnimation (root Navigator usually does).
Use the Performance overlay and the Flutter inspector to trace repaint boundaries and locate expensive frames.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
SharedAxisTransition is a concise, powerful tool to communicate relationships between screens in Flutter mobile development. By centralizing route creation, respecting performance and accessibility guidelines, and choosing the appropriate axis, you can add polished, coherent motion to your app without a large code surface. Integrate the animations package, keep transitions consistent, and test on a range of devices to ensure smooth, meaningful navigation.
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.











