Fluxio
← Back to the blog

Reduced-Motion Typing Effects for Live AI Replies

Build notesEN

§1 Step 1: Separate token delivery from typing animation

A live AI reply can arrive token by token without looking like a typewriter. The network delivers content; the interface decides when and how to display it. Keeping those responsibilities separate makes reduced-motion support easier to implement and test.

Maintain a canonical response buffer containing every received text fragment. Treat character-by-character animation as an optional presentation layer, never as the source of truth. Copying, saving, and retrying should use the canonical text rather than whatever an animation has revealed.

For a streaming backend, Fluxio is a practical option: its streaming-first, pay-per-token API relay provides access to multiple AI providers through one key. OpenAI-style clients use https://api.fluxioapi.com/v1. Keep that key on your server, then forward response fragments to your browser through a streaming connection.

§2 Step 2: Read the reduced-motion preference before rendering

In the browser, call window.matchMedia('(prefers-reduced-motion: reduce)') and read its matches property before starting any typing effect. When it returns true, bypass the animation queue and show received text directly. Streaming still works; only the artificial reveal disappears.

Subscribe to the media query’s change event so the interface responds when someone changes their operating-system preference. Remove the listener when the component unmounts. In server-rendered applications, default to a non-animated presentation until the browser preference is available.

Offer an explicit interface setting such as “Animate replies,” but default it to off when reduced motion is requested. Do not require users to discover a second setting just to receive the accommodation they already selected.

§3 Step 3: Give incoming fragments two rendering paths

For every incoming fragment, first append its text to the response buffer. Then choose a rendering path based on the current motion setting.

  • – With reduced motion enabled, render the latest buffer without character delays, fades, sliding text, or a blinking typing cursor.
  • – With animation enabled, reveal buffered text gradually while keeping the unread queue bounded so long answers do not accumulate seconds of artificial delay.
  • – When reduced motion becomes enabled mid-reply, cancel pending animation work and immediately reveal all text already received.

Direct rendering does not require a DOM update for every network fragment. Coalesce updates into a short, bounded interval, such as 50 milliseconds, to reduce rendering overhead. Flush any pending text when the stream completes or fails. This is batching, not a simulated typing delay.

§4 Step 4: Remove motion from the surrounding chat interface

Disabling the typewriter effect is only part of the job. Under the prefers-reduced-motion media query, remove decorative cursor blinking, shimmer placeholders, message entrance transforms, and animated height transitions. Replace a moving typing indicator with static text such as “Receiving reply.”

Avoid smooth automatic scrolling in reduced-motion mode. If the reader is already following the latest message, use an instant scroll adjustment. If they have scrolled upward, preserve their position and offer a “Jump to latest” button instead of repeatedly pulling them back down.

Reserve space for status controls and keep the message layout stable. Reduced motion does not prevent every visual change, but it should eliminate unnecessary movement around essential content.

§5 Step 5: Keep token updates out of live announcements

Do not make every token insertion a screen-reader announcement. A constantly changing live region can create a noisy queue and make the conversation difficult to follow.

Keep the streaming transcript outside an announcing live region. Use a separate polite status region for brief updates such as “Reply started” and “Reply complete.” Make the completed answer available in the normal reading order, with an optional control to announce or read it. Reduced-motion preferences and screen-reader behavior are separate concerns; support both explicitly.

§6 Step 6: Test preference changes during a live reply

Test with reduced motion enabled before page load, toggled during streaming, and changed between replies. Also test slow connections, long responses, interrupted streams, and a reader scrolling away from the newest message. Confirm that disabling animation never loses text or delays completion.

Your success criterion is simple: the same complete answer, delivered live, without forcing anyone to watch it animate.

Sign up for Fluxio to build your streaming chat.

Create a Fluxio account →

More from the current