reduce-motion
A cross-platform skill to detect and honor user motion preferences in UI animations.
Install
mkdir -p .claude/skills/reduce-motion && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15321" && unzip -o skill.zip -d .claude/skills/reduce-motion && rm skill.zipInstalls to .claude/skills/reduce-motion
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Detecting and honoring the user's reduce motion preference on iOS, Android, Flutter, and React Native. Use this when building transitions, parallax, hero animations, or autoplay.Key capabilities
- →Detect user's reduce motion preference on iOS, Android, Flutter, and React Native
- →Disable parallax, hero scroll effects, and decorative wobble for reduced motion
- →Replace slide/zoom transitions with crossfade for accessibility
- →Shorten animation durations to less than 100ms for non-essential motion
- →Stop autoplaying video, carousels, and Lottie backgrounds
How it works
The skill detects the system's reduce motion setting across various platforms and provides guidelines for disabling or replacing non-essential motion. It suggests using crossfade for transitions and shortening durations.
Inputs & outputs
When to use reduce-motion
- →Building accessible transitions
- →Adapting animations for vestibular health
- →Implementing motion-safe UI
About this skill
Reduce Motion
Instructions
Some users experience nausea or vertigo from screen motion (vestibular disorders). Every OS ships a system toggle. Honor it for non-essential motion; keep essential feedback (progress indicator).
1. Detecting the Setting
iOS (UIKit):
UIAccessibility.isReduceMotionEnabled
NotificationCenter.default.addObserver(
forName: UIAccessibility.reduceMotionStatusDidChangeNotification,
object: nil, queue: .main
) { _ in /* update state */ }
iOS (SwiftUI):
@Environment(\.accessibilityReduceMotion) private var reduceMotion
.animation(reduceMotion ? nil : .spring(), value: offset)
Android (API 33+):
val am = context.getSystemService(AccessibilityManager::class.java)
val reduced = am.isEnabled &&
Settings.Global.getFloat(contentResolver,
Settings.Global.TRANSITION_ANIMATION_SCALE, 1f) == 0f
A simpler heuristic used across libraries:
fun areAnimationsDisabled(context: Context): Boolean {
return Settings.Global.getFloat(
context.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1f
) == 0f
}
Jetpack Compose:
val reduce = LocalAccessibilityManager.current?.run {
// API 33+: expose via custom CompositionLocal backed by AccessibilityManager
false
} ?: areAnimationsDisabled(LocalContext.current)
val anim: AnimationSpec<Float> = if (reduce) snap() else spring()
Flutter:
final disableAnimations = MediaQuery.disableAnimationsOf(context);
AnimatedContainer(
duration: disableAnimations ? Duration.zero : const Duration(milliseconds: 300),
curve: Curves.easeOut,
// ...
)
React Native:
import { AccessibilityInfo } from 'react-native';
const [reduce, setReduce] = useState(false);
useEffect(() => {
AccessibilityInfo.isReduceMotionEnabled().then(setReduce);
const sub = AccessibilityInfo.addEventListener('reduceMotionChanged', setReduce);
return () => sub.remove();
}, []);
Reanimated helper:
import { useReducedMotion } from 'react-native-reanimated';
const reduce = useReducedMotion();
2. What To Disable or Replace
When reduce motion is on:
- Disable parallax on cards, hero scroll effects, and decorative wobble.
- Replace slide/zoom transitions with crossfade (WCAG-compatible, no translation).
- Shorten durations — keep timing for feedback (e.g., button press) but prefer < 100ms.
- Stop autoplaying video, carousels, and Lottie backgrounds. Provide a play control.
- Skip large scale/translate transforms; keep opacity changes.
3. Hero / Shared-Element Transitions
SwiftUI example — crossfade fallback:
if reduceMotion {
detail.transition(.opacity)
} else {
detail.transition(.asymmetric(insertion: .move(edge: .trailing),
removal: .opacity))
}
Compose:
val enter = if (reduce) fadeIn() else slideInHorizontally() + fadeIn()
AnimatedContent(target = screen, transitionSpec = { enter togetherWith fadeOut() }) { /* ... */ }
Flutter navigation:
MaterialPageRoute(
builder: (_) => const DetailPage(),
allowSnapshotting: !disableAnimations,
// wrap with PageRouteBuilder for fade transition when reduced
)
4. Skeletons and Loaders
- Replace shimmer/pulse with a static placeholder + a subtle opacity breathe (< 0.2 delta).
- Progress spinners are "essential" motion — keep them. Use
@Environment(\.accessibilityReduceMotion)to swap large marketing loaders for a plainProgressView.
5. Vestibular Red Flags
Avoid, or provide reduce-motion fallback, for:
- Parallax with scroll parallax factor > 0.2.
- Full-screen page-flip or 3D rotation.
- Auto-scrolling carousels (also a WCAG 2.2.2 issue).
- Particle effects, confetti without user trigger.
- Background videos on splash / home.
6. Flashing Content
Regardless of the user's preference, never exceed 3 flashes per second (WCAG 2.3.1). Even one large red flash can trigger photosensitive seizures.
7. In-App Override
If your brand requires motion-rich content, add an in-app "Reduce animations" toggle that mirrors the system flag and is also respected by your code path. Default = system value.
8. Testing
- iOS: Settings → Accessibility → Motion → Reduce Motion (and separately Prefer Cross-Fade Transitions).
- Android: Developer options →
Window animation scale,Transition animation scale,Animator duration scale→ Off. Also Settings → Accessibility → Remove animations on Android 12+. - Flutter:
flutter test --platform chrome --dart-define=flutter.inspector.structuredErrors=true+ wrap app with MediaQuery disabling animations. - RN: Jest + mock
AccessibilityInfo.isReduceMotionEnabled.
9. Common Pitfalls
- Applying reduce-motion only to one animation out of ten.
- Shortening duration but keeping 300px translate — still nauseating.
- Using a third-party animation lib that ignores the flag; check its docs.
- Replacing animation with a pop (instant change) when crossfade would feel less jarring.
- Autoplay carousels with no pause control.
Checklist
- Reduce-motion flag read once, exposed app-wide (env/provider/hook).
- All non-essential transitions degrade to crossfade or instant.
- Parallax, wobble, and decorative motion disabled when flag is on.
- Autoplay video / carousels offer pause and respect the flag.
- No content flashes > 3x/sec in any 1s window.
- In-app toggle mirrors system setting (optional but recommended).
- Tested with reduce motion on, animator scale 0, and Flutter
disableAnimations.
When not to use it
- →When building essential feedback animations like progress indicators
- →When the UI does not involve transitions, parallax, or autoplay
- →When exceeding 3 flashes per second, which is a WCAG violation regardless of preference
Limitations
- →Requires explicit implementation for each platform (iOS, Android, Flutter, React Native)
- →Does not apply to essential motion like progress spinners
- →Third-party animation libraries may ignore the flag
How it compares
This skill provides platform-specific code examples and guidelines for adapting UI motion to user accessibility preferences, ensuring compliance with standards, unlike a generic approach to animation.
Compared to similar skills
reduce-motion side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| reduce-motion (this skill) | 0 | 4mo | No flags | Intermediate |
| mobile-android-design | 101 | 2mo | No flags | Intermediate |
| mobile-design | 149 | 4mo | Review | Intermediate |
| mobile-developer | 5 | 4mo | No flags | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by almasumdev
View all by almasumdev →You might also like
mobile-android-design
wshobson
Master Material Design 3 and Jetpack Compose patterns for building native Android apps. Use when designing Android interfaces, implementing Compose UI, or following Google's Material Design guidelines.
mobile-design
sickn33
Mobile-first design and engineering doctrine for iOS and Android apps. Covers touch interaction, performance, platform conventions, offline behavior, and mobile-specific decision-making. Teaches principles and constraints, not fixed layouts. Use for React Native, Flutter, or native mobile apps.
mobile-developer
sickn33
Develop React Native, Flutter, or native mobile apps with modern architecture patterns. Masters cross-platform development, native integrations, offline sync, and app store optimization. Use PROACTIVELY for mobile features, cross-platform code, or app optimization.
mobile-components
dadbodgeoff
Mobile-first UI components including bottom navigation, bottom sheets, pull-to-refresh, and swipe actions. Touch-optimized with proper gesture handling.
ui-mobile
alinaqi
Mobile UI patterns - React Native, iOS/Android, touch targets
iOS Animation Graphics Skill
bsreeram08
Creating animations and graphics using SwiftUI Canvas, Core Animation, and Lottie integration for engaging iOS app experiences.