Repository navigation
fix(Layer): under a finger with Reduce Motion, a layer fades in instead of appearing at once - #8322
Conversation
…ad of appearing at once The shared layer entrance (layerAnimations) dropped its animation under prefers-reduced-motion, so a Tooltip, HoverCard or menu opened by a tap appeared in one frame. On a touch screen Reduce Motion replaces motion with a cross-fade, never a jump: under a coarse pointer the entrance now keeps its opacity ramp and drops only the travel and the scale. Under a mouse it still appears at once, and without Reduce Motion nothing changes. LayerReducedMotion.a11y.chromium.spec.ts proves the three cases in a real engine (media queries), with its own pr-a11y step.
The current design:reduced-motion record (DR2) asks a core component under Reduce Motion on a coarse pointer to cross-fade, opacity only, in 200 ms or less, and DR3 asks other pointers to change at once. The touch fade took the theme's --duration-fast-max, 165 ms with the default motion scale but 230 ms without one and longer in a slower theme. Under a coarse pointer with Reduce Motion it is now min(--duration-fast-max, 200ms); everything else is unchanged. The Chromium contract checks the fade's duration, and a slow-theme case (--duration-fast-max: 400ms) proves the cap: 0.4 s before, 0.2 s now.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
There was a problem hiding this comment.
This review recommends approval. Under Reduce Motion on a touch screen, layers that use the shared entrance now fade in place, opacity only and within 200 ms, as design:reduced-motion DR2 requires; mouse and no-preference entrances stay as they were. The new Chromium contract fails against main's build and passes on this head, and the 200 ms cap holds for slower themes in Chromium and WebKit. Nothing further is needed from you.
[Automated review]
PR Analysis Report📚 Storybook Preview🧪 Sandbox PreviewNo new or modified components detected. Bundle Size Summary
Accessibility AuditStatus: No accessibility violations detected. Visual Regression46 of 494 shot(s) changed. A change here is a question, not a failure: check whether the after is the
and 26 more. Generated by PR Enrichment workflow | Storybook | Sandbox | View full report |
Supersedes #8214, which #8272's merge closed through its closing keyword; same branch, plus the 200 ms cap that
design:reduced-motionasks for.User impact
With Reduce Motion on, a Tooltip, HoverCard, menu or other layer that opens under a finger appeared in a single frame: the shared layer entrance dropped its whole animation, fade included. On a touch screen Reduce Motion replaces motion with a cross-fade, never a jump.
Evidence
iOS 26.2 Safari with Reduce Motion on, a tap on the Tooltip's term (a grey dot drawn by the test page marks the finger); before (main), then after:
--duration-fast-max: 400ms) fails without the cap (0.4 s) and passes with it (0.2 s).Problem and solution fit
layerAnimations(the entrance every layer applies throughlayer.render) setanimation-name: noneunderprefers-reduced-motion: reduce. That suits a mouse. Under a coarse pointer it is a jump where iOS fades.Under a coarse pointer with Reduce Motion the entrance now keeps its opacity ramp, drops the slide and the scale, and lasts
min(--duration-fast-max, 200ms). Under a mouse it still appears at once; without Reduce Motion nothing changes. Components with their own touch presentation (DropdownMenu, Popover in the open stacks) override this entrance inline, so this reaches layers that have none: Tooltip, HoverCard, Selector, ContextMenu and the like.Expected behavior and authority
design:reduced-motion(current): under reduced motion nothing moves, scales or springs (DR1); on a coarse pointer it cross-fades, opacity only, in 200 ms or less (DR2); on other pointers it changes at once (DR3); no theme value keeps motion (DR4).Smallest restoration
One added media condition per placement in
layerAnimations.stylex.ts(a fade keyframe, and the capped duration), and a real-engine contract with its own pr-a11y step. A UIKit-timed touch entrance for tooltips is an open owner question (D7), not built here.Scope
Testing
pnpm exec playwright test packages/core/src/Layer/__tests__/LayerReducedMotion.a11y.chromium.spec.ts --project chromiumafterpnpm storybook:build: 8/8 (Tooltip and HoverCard: an opacity-only fade of 200 ms or less under a finger with Reduce Motion, also with a slow theme; unchanged without it; still instant under a mouse). The fade cases fail against main; the slow-theme case fails against fix(Layer): under a finger with Reduce Motion, a layer fades in instead of appearing at once #8214's head.pnpm vitest run .github/scripts/ci-test-routing.test.mjs .github/scripts/release-check-workflow.test.mjs: 101 pass.pnpm vitest run packages/core/src/Layer packages/core/src/Tooltip packages/core/src/HoverCard packages/core/src/Popover packages/core/src/DropdownMenu packages/core/src/Selector packages/core/src/ContextMenu: 983 pass.