Archify Viewer Animation Options and prefers-reduced-motion Accessibility Support
Archify viewer animations default to 540ms CSS transitions for pan, zoom, and panel effects, automatically disabling when prefers-reduced-motion: reduce is detected via JavaScript MediaQueryList detection and CSS media query fallbacks.
The Archify viewer provides smooth UI animations for architectural model navigation, including panel reveals, hover effects, and smooth scrolling. These animations are fully configurable and respect user accessibility preferences through the standard prefers-reduced-motion media feature. This article examines the animation system in the tt-a1i/archify repository and explains how reduced-motion detection is implemented across both JavaScript and CSS layers.
Core Animation Parameters in the Archify Viewer
The viewer uses a consistent timing system for all animated transitions.
| Animation Property | Default Value | Controlled By |
|---|---|---|
| Transition duration | 540 ms |
Hard-coded delay variable in viewer JS |
| Scroll behavior | smooth |
CSS scroll-behavior property |
| Element transitions | opacity, transform |
Component-level CSS classes |
The 540 ms duration appears throughout the codebase as the standard timing for panel fades, slide-ins, and smooth-scroll actions. This value is defined conditionally based on the reduced-motion state rather than being modified directly.
How prefers-reduced-motion Detection Works
The Archify viewer implements a two-layer approach: JavaScript runtime detection and CSS media query fallbacks.
JavaScript Media Query Detection
The viewer creates a MediaQueryList object early in initialization to monitor the user's motion preference:
const reducedMotionQuery = window.matchMedia
? window.matchMedia('(prefers-reduced-motion: reduce)')
: null;
This query is also referenced as motionQuery in some viewer scripts. The current state is accessed through the .matches property:
const reduced = reducedMotionQuery && reducedMotionQuery.matches;
The reduced boolean flag then drives conditional logic throughout the UI codebase. In examples/checkout-platform-delta.html around line 15126, this pattern controls animation timing:
const delay = reduced ? 0 : 540;
const transition = reduced ? 'none' : 'opacity 540ms ease';
CSS Fallback Protection
In scripts/start-template.html, a comprehensive media query block ensures no transitions escape the reduced-motion preference:
@media (prefers-reduced-motion: reduce) {
* { scroll-behavior: auto !important; }
.canvas[data-delta-review-active] [data-delta-review-current] {
transition: none !important;
}
}
This CSS layer catches any animations that the JavaScript logic might miss, providing defense-in-depth for accessibility compliance.
Animation Features and Their Reduced-Motion Behavior
Panel Transitions and Reveals
Panel animations—used for layer controls, property inspectors, and navigation sidebars—rely on the conditional delay pattern. When prefers-reduced-motion: reduce is active, panels appear instantly at full opacity without slide or fade effects.
Pan and Zoom Operations
Smooth camera movements in the 3D canvas use the same 540 ms easing by default. The reduced-motion path executes view changes immediately, jumping directly to target positions without interpolation.
Scroll-Based Navigation
Smooth scrolling is disabled through the CSS scroll-behavior: auto !important override in the media query block. This affects:
- Anchor link navigation within long documentation panels
- Programmatic scroll-to-element calls
- Wheel/trackpad scrolling behavior
Hover Effects
Interactive elements that normally transition on :hover states lose their transition properties entirely when reduced motion is preferred, rendering state changes instant.
Implementing prefers-reduced-motion in Custom Archify Components
When extending the Archify viewer, follow the established pattern for motion respect.
JavaScript Helper Pattern
Create a reusable detection function consistent with the viewer's approach:
function isReducedMotion() {
return !!(window.matchMedia &&
window.matchMedia('(prefers-reduced-motion: reduce)').matches);
}
// Apply to animation timing
const animationDelay = isReducedMotion() ? 0 : 540;
element.style.transition = isReducedMotion()
? 'none'
: `transform ${animationDelay}ms ease`;
CSS Defensive Pattern
Include the media query block in any custom HTML templates:
@media (prefers-reduced-motion: reduce) {
* { scroll-behavior: auto !important; }
.panel, .canvas, .tooltip {
transition: none !important;
}
}
View Change Routine Example
For custom view transitions, mirror the viewer's conditional duration logic:
function animateViewChange(target) {
const duration = isReducedMotion() ? 0 : 540;
// Execute view change logic
setTimeout(() => { /* finalize state */ }, duration);
}
Key Source Files for Animation Behavior
| File | Responsibility |
|---|---|
scripts/start-template.html |
Global CSS media query block, main viewer layout structure |
examples/web-app.html |
motionQuery / reducedMotionQuery initialization, 540ms delay application |
examples/checkout-platform-delta.html |
Conditional delay logic demonstration at scale (line 15126) |
Viewer-generated .js bundles |
Runtime window.matchMedia checks, parameter swapping |
These files demonstrate that animation control is distributed across both declarative CSS and imperative JavaScript, with each layer capable of independently enforcing reduced-motion preferences.
Browser and OS Support
The prefers-reduced-motion media feature is supported in all modern browsers. Users typically enable this preference through:
- macOS/iOS: System Preferences → Accessibility → Display → Reduce Motion
- Windows: Settings → Ease of Access → Display → Show animations
- Android: Settings → Accessibility → Remove animations
- Chrome OS: Settings → Advanced → Accessibility → Manage accessibility features → Enable animations (toggle off)
The Archify viewer detects these system-level changes immediately through the MediaQueryList live query, without requiring page refresh.
Summary
- Default animations in the Archify viewer use a 540 ms duration for all transitions, hard-coded in the viewer's JavaScript.
prefers-reduced-motion: reduceis detected viawindow.matchMedia('(prefers-reduced-motion: reduce)')and stored inreducedMotionQuery/motionQueryvariables.- When reduced motion is preferred, the viewer sets delay to 0 ms, applies transition: none, and disables smooth scrolling.
- CSS media queries in
scripts/start-template.htmlprovide fallback protection for any animations missed by JavaScript logic. - All animation code paths branch on the
reducedboolean flag, ensuring consistent instant state changes when accessibility preferences demand it.
Frequently Asked Questions
How do I test reduced-motion behavior in the Archify viewer without changing system settings?
Most browsers provide emulation tools. In Chrome DevTools, open the Rendering panel and check "Emulate CSS media feature prefers-reduced-motion" with the value set to reduce. This immediately triggers the viewer's reduced-motion code paths without modifying your operating system preferences.
Does the Archify viewer support partial animation reduction or only full disable?
The current implementation in tt-a1i/archify uses a binary approach: animations run at full 540 ms duration or are completely disabled with 0 ms delay and transition: none. There is no intermediate "reduced" speed setting. The conditional logic follows the pattern reduced ? 0 : 540 throughout the codebase.
Why does the viewer use both JavaScript and CSS to handle prefers-reduced-motion?
The dual-layer approach ensures accessibility resilience. JavaScript detection in examples/web-app.html and related scripts allows dynamic, runtime-responsive animation control for programmatic transitions. The CSS media query in scripts/start-template.html acts as a safety net for styles that might be applied outside JavaScript's control or loaded from external sources.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →