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: reduce is detected via window.matchMedia('(prefers-reduced-motion: reduce)') and stored in reducedMotionQuery / motionQuery variables.
  • 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.html provide fallback protection for any animations missed by JavaScript logic.
  • All animation code paths branch on the reduced boolean 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →