You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
overview: Prevent delayed entrance flashes without changing IntersectionObserver geometry by making the transient neutral styles author-important, using real zero delays, and giving entrance effects backwards fill by default. Align validation, documentation, and Interactor guidance with the runtime behavior.
4
+
todos:
5
+
- id: important-initial-css
6
+
content: Emit author-important transient FOUC declarations and preserve true zero animation delays
7
+
status: completed
8
+
- id: entrance-fill-defaults
9
+
content: Default every entrance preset descriptor to backwards fill while preserving explicit overrides
10
+
status: completed
11
+
- id: validation-guidance
12
+
content: Add backwards-fill validation guidance and align Interact docs, rules, and Interactor skill
13
+
status: completed
14
+
- id: regression-tests
15
+
content: Cover CSS serialization, timing, all entrance presets, validator behavior, and run targeted verification
16
+
status: completed
17
+
isProject: false
18
+
---
19
+
20
+
# Fix Delayed Entrance FOUC
21
+
22
+
## Implementation
23
+
24
+
- Extend the internal declaration shape in [`packages/interact/src/types/css.ts`](packages/interact/src/types/css.ts) with an `important` flag and serialize it in [`packages/interact/src/core/cssUtils.ts`](packages/interact/src/core/cssUtils.ts). Mark every [`DEFAULT_INITIAL`](packages/interact/src/core/css.ts) declaration important so `visibility: hidden` and neutral transform properties override pre-trigger animation values, while retaining the existing `:not([data-interact-enter])` lifecycle.
25
+
- In [`packages/motion/src/api/cssAnimations.ts`](packages/motion/src/api/cssAnimations.ts), replace the synthetic `delay || 1` fallback with `delay ?? 0`. Do not add the proposed `0.1ms` initial override, because it would alter computed sequence timing and could move a playing animation back from its active phase into its delay phase.
26
+
- Add a small `getEntranceFill()` helper in [`packages/motion-presets/src/utils.ts`](packages/motion-presets/src/utils.ts), returning `options.fill ?? 'backwards'`. Apply it after `...options` to every animation descriptor in all 19 modules under [`packages/motion-presets/src/library/entrance/`](packages/motion-presets/src/library/entrance/) so both CSS and WAAPI paths default to backwards fill while explicit `none`, `forwards`, or `both` values remain authoritative.
27
+
28
+
## Validation and guidance
29
+
30
+
- Add an informational `RECOMMENDED_FILL_BACKWARDS` semantic check in [`packages/interact-validate/src/semantic/recommendedPatterns.ts`](packages/interact-validate/src/semantic/recommendedPatterns.ts), wire it through [`collectSemanticWarnings.ts`](packages/interact-validate/src/semantic/collectSemanticWarnings.ts) and [`errors.ts`](packages/interact-validate/src/errors.ts), and recommend explicit `backwards` or `both` for effective `viewEnter`/`once` animation effects, including nested sequence effects. Keep this advisory so preset defaults remain a safety net rather than a schema requirement.
31
+
- Update the authoritative entrance/FOUC guidance and generated CSS examples in [`packages/interact/rules/viewenter.md`](packages/interact/rules/viewenter.md), [`packages/interact/rules/full-lean.md`](packages/interact/rules/full-lean.md), [`packages/interact/docs/api/functions.md`](packages/interact/docs/api/functions.md), and [`packages/interact/docs/examples/entrance-animations.md`](packages/interact/docs/examples/entrance-animations.md): explain the important neutral pre-trigger rule, use `fill: 'backwards'` for `once`, and reserve `both` for effects that must retain their final keyframe.
32
+
- Update the repository Interactor source in [`skills/interactor/SKILL.md`](skills/interactor/SKILL.md) plus its `config-schema`, `triggers`, `integration-recipes`, and `validate` references. Make explicit backwards fill an invariant in generated `viewEnter`/`once` configs and update the relevant eval expectation; do not manually edit external installed skill snapshots.
33
+
34
+
## Regression coverage
35
+
36
+
- Update [`packages/interact/test/css.spec.ts`](packages/interact/test/css.spec.ts) and [`cssUtils.spec.ts`](packages/interact/test/cssUtils.spec.ts) to verify important initial declarations are emitted only for eligible same-element `viewEnter`/`once` effects and disappear from the post-start selector.
37
+
- Update [`packages/motion/test/motion.spec.ts`](packages/motion/test/motion.spec.ts) to assert omitted/zero delay produces `0ms`, while positive delays remain unchanged.
38
+
- Add centralized entrance-preset tests covering all 19 exports: every generated descriptor defaults to `backwards`, and an explicit fill value is preserved. Retain existing per-preset behavior tests and add coverage for the currently untested `ExpandIn` export through this matrix.
39
+
- Add validator tests for direct effects, referenced registry effects, sequence effects, implicit `once`, accepted `backwards`/`both`, and informational severity/category overrides.
40
+
41
+
## Verification
42
+
43
+
- Run `nvm use`, then targeted tests and type checks for `@wix/motion`, `@wix/motion-presets`, `@wix/interact`, and `@wix/interact-validate`; finish with repository lint/format checks for touched files.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+67-1Lines changed: 67 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,6 +10,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
10
10
11
11
## @wix/splittext
12
12
13
+
### [0.2.0] - unreleased
14
+
15
+
#### Added
16
+
17
+
-`@wix/splittext/plugin` entry points: `splitTextPlugin` for `Interact.use()`, and `splitTextStyle` for `generate()` (#275)
18
+
-`hideUntilReady`: `splitTextStyle` hides the container until the runtime split sets `data-splittext-ready` (#275)
19
+
13
20
### [0.1.2] - 2026-07-14
14
21
15
22
#### Added
@@ -26,6 +33,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
26
33
27
34
## @wix/interact-validate
28
35
36
+
### [0.2.0] - unreleased
37
+
38
+
#### Added
39
+
40
+
- Plugin fields: `$`-prefixed keys on interactions and effects are accepted; every other unknown key is still reported as `SCHEMA_UNRECOGNIZED_KEYS` (#275)
41
+
42
+
#### Changed
43
+
44
+
-`KEYFRAME_PROP_NOT_CAMEL_CASE` (rule category `KEYFRAME_STYLE`) is replaced by `INVALID_CSS_PROPERTY_NAME` (rule category `CSS_PROPERTY_NAME`): both camelCase and kebab-case CSS property names are valid input, so only names that are neither are reported, and the check now covers `transition.styleProperties` / `transitionProperties` names in addition to `keyframeEffect` keyframes
45
+
-`severityOverrides` keyed on `KEYFRAME_STYLE` are now silently ignored. Rename the key to `CSS_PROPERTY_NAME` to keep an override in effect
46
+
47
+
### [0.1.2] - 2026-07-29
48
+
49
+
#### Added
50
+
51
+
-`RECOMMENDED_FILL_BACKWARDS` semantic check nudging `viewEnter` + `once` keyframe/named effects without FOUC hiding rules to set `fill: 'backwards'` or `'both'` (#277)
52
+
53
+
#### Changed
54
+
55
+
- README rule catalog updated for `RECOMMENDED_FILL_BACKWARDS` (#277)
56
+
29
57
### [0.1.1] - 2026-07-14
30
58
31
59
#### Added
@@ -53,17 +81,37 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
53
81
54
82
## @wix/interact
55
83
56
-
### [2.6.0] - 2026-07-28
84
+
### [2.6.0] - unreleased
57
85
58
86
#### Added
59
87
88
+
- Generic plugin bridge: `Interact.use(name, plugin)` registers a plugin, and a `$<name>` field on an interaction or effect (#275)
89
+
-`generate()` accepts a `plugins` option — a map of plugin name → build-time style generator (#275)
60
90
- Reduced motion is now detected from the browser: `Interact.forceReducedMotion` reads `prefers-reduced-motion` unless it was set explicitly, and the browser setting is re-read as each interaction is bound
61
91
-`generate()` accepts a third `options` argument and emits `@media (prefers-reduced-motion: reduce)` overrides by default — animations that run once collapse to `1ms` and land on their end state, perpetual and scroll-driven animations are turned off, transitions are dropped. Pass `{ reducedMotion: false }` to opt out
62
92
63
93
#### Changed
64
94
95
+
-`generate(config, options?)`: the second argument now accepts an options bag — `{ useFirstChild?, plugins? }` — exported as the `GenerateOptions` (#275)
96
+
- CSS property names may be authored in either camelCase or kebab-case in `transition.styleProperties`, `transitionProperties` and `keyframeEffect.keyframes`; state-effect properties are normalized to kebab-case for the generated CSS (state rules and the `transition:` shorthand) and keyframes to camelCase for WAAPI
65
97
-`Interact.forceReducedMotion = false` now means "ignore the browser setting and animate" instead of "use the default"; assign `undefined` to go back to browser detection
66
98
99
+
#### Fixed
100
+
101
+
- camelCase property names in `transition.styleProperties` / `transitionProperties` are now normalized to kebab-case
102
+
- CSS custom properties in keyframes (e.g. `--fooBar`) are no longer lower-cased when emitted into `@keyframes`
103
+
- Vendor-prefixed keyframe properties (e.g. `webkitTextStroke`) now emit a valid CSS property name (`-webkit-text-stroke`)
104
+
105
+
### [2.5.5] - 2026-07-29
106
+
107
+
#### Fixed
108
+
109
+
- Entrance FOUC prevention: `generate()` initial rules now emit `!important` on transform neutralization declarations so they override inline styles until the animation starts (#277)
110
+
111
+
#### Changed
112
+
113
+
-`viewEnter` rules and docs recommend `fill: 'backwards'` (or `'both'`) for entrance animations; CSS rule declarations support an optional `important` flag (#277)
114
+
67
115
### [2.5.4] - 2026-07-16
68
116
69
117
#### Fixed
@@ -270,12 +318,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
270
318
271
319
#### Added
272
320
321
+
-`toCSSPropertyName()`, `toWAAPIPropertyName()` and `normalizeKeyframes()` utilities for converting CSS property names between their CSS and WAAPI forms
273
322
-`getCSSAnimation()` accepts a `{ reducedMotion }` option so generated CSS can express the same reduced-motion behavior as the Web Animations path — animations that run once collapse to a `1ms` duration, while perpetual and scrub-driven animations are skipped
274
323
275
324
#### Changed
276
325
326
+
- Keyframe property names may be authored in either camelCase or kebab-case and are normalized to WAAPI's camelCase on every animation path — `keyframeEffect`, presets, and effects registered via `registerEffects()`
277
327
- The reduced-motion rule shared by the Web Animations and CSS paths lives in a single `getReducedMotionOptions()` helper
278
328
329
+
### [2.1.8] - 2026-07-29
330
+
331
+
#### Added
332
+
333
+
-`getWebAnimation()` accepts SVG elements (and any `Element`) as keyframe targets, not only `HTMLElement` (#280)
334
+
335
+
#### Changed
336
+
337
+
-`getCSSAnimation()` delay serialization: use `0ms` when `delay` is `0` instead of previously defaulting to `1ms` (#277)
338
+
279
339
### [2.1.7] - 2026-05-29
280
340
281
341
#### Added
@@ -354,6 +414,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
354
414
355
415
## @wix/motion-presets
356
416
417
+
### [1.0.4] - 2026-07-29
418
+
419
+
#### Changed
420
+
421
+
- Entrance presets default to `fill: 'backwards'` via `getEntranceFill()` unless overridden (#277)
0 commit comments