Accessibility
Reduced motion, contrast for dithered text, and the semantics of each component.
Reduced motion
Animation freezes under reduced motion on every platform. Stipple reads the setting from:
| Target | Source |
|---|---|
| Android | ValueAnimator.areAnimatorsEnabled(), and Compose’s MotionDurationScale, which is 0 when animations are off. |
| iOS | Reduce Motion in Accessibility settings. |
| wasmJs | The prefers-reduced-motion: reduce media query. |
| JVM desktop | No system source: motion is full unless you override it. |
You can override it with LocalStippleMotion (System, Full or Reduced). Read the resolved value with isStippleMotionReduced().
A frozen field is drawn at the modifier’s stillTime. Progress and value changes still update, because they are information, not decoration.
Contrast
DitherText keeps text readable. If the contrast between ink and paper falls below minContrast (4.5 by default), it swaps the ink for black or white. theme.contrastRatio gives the ratio for any theme.
DitherEffectText shows its finished text at once under reduced motion, and a screen reader always reads the final text, never a scrambled frame.
Keep the field’s tone under about 0.5 where text sits on a dithered background.
Semantics
Components expose normal semantics:
DitherButtonhas a button role, focus and press states, and its text.DitherProgressBarandDitherGaugereport their value as a range.DitherBarChart,DitherGridandDitherGaugetake acontentDescription, andDitherStatCarddescribes its label, value and delta as one element.DitherImageandDitherAvatartake a description or a name.
A plain Modifier.dither is decoration and is invisible to screen readers. If it carries meaning, give the element its own semantics.