Docs · 11 pages
Docs / Checks
Accessibility
The reduced-motion policy every component follows, and the details screen readers care about.
Reduced motion
Every component has a prefers-reduced-motion: reduce branch, and the test
suite refuses a component without one. The policy is cross-fade instead of
movement, never a hard cut, never nothing:
- Reveal and SplitText keep a fast opacity fade and drop translate, scale, blur and stagger.
- RotatingText crossfades in place instead of rising.
- Typewriter shows the full text at once; the caret stops blinking.
- Marquee stops, hides its duplicate copies, and becomes a scrollable strip so every item is reachable.
- Aurora becomes a static gradient.
Scripts read the preference through the runtime’s prefersReducedMotion() and
shorten motion to near-zero rather than skipping the code path, so end states
still apply.
Previewing reduced motion
The header of this site has a motion switch. It sets
data-ma-motion="reduce" on <html>, and every reduced-motion rule on the
page (the components’, Tailwind’s motion-reduce: utilities, the site’s own)
also applies under that attribute, so the switch shows what the media query
does without changing an OS setting. The exception is motion that only a
(prefers-reduced-motion: no-preference) block turns on: the attribute does
not stop it. Nothing is duplicated by hand: the
integration’s motionAttribute option mirrors the @media (prefers-reduced-motion: reduce) blocks at build time, and
prefersReducedMotion() in the runtime reads the attribute as well as the
media query. Turn it on in your own project with
moonarc({ motionAttribute: true })and stamp the attribute from a toggle of your own. It costs a few percent of CSS and no JavaScript.
Content is never hidden by default
Server HTML is the end state. Entrance effects hide content only behind
html[data-ma-js], which the integration sets just before first paint. If
JavaScript fails or is disabled, the page is simply visible.
Text components
SplitText and Typewriter keep the whole string in a visually hidden copy
(.ma-sr) and mark the animated parts aria-hidden, so assistive tech reads
one string rather than a stream of letters. RotatingText’s hidden copy lists
every word once. Marquee’s duplicate copies are aria-hidden and inert,
so their links are not reached twice. Aurora is aria-hidden outright.
Pointer gating
Hover effects are gated on (hover: hover) and (pointer: fine) so touch
devices never trigger them on tap.