Skip to content

feat(CSS): animate backgroundImage gradients on web - #10592

Closed
MatiPl01 wants to merge 5 commits into
@matipl01/css-background-image-tests-docsfrom
@matipl01/css-background-image-web
Closed

MatiPl01 wants to merge 5 commits into
@matipl01/css-background-image-tests-docsfrom
@matipl01/css-background-image-web

Conversation

@MatiPl01

@MatiPl01 MatiPl01 commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Note

This pull request was authored by AI on behalf of @MatiPl01.

Summary

CSS animations and transitions of backgroundImage (native support in #10590) had no web processor, so gradients in keyframes were dropped. This adds a serializer that turns the React Native gradient object form into CSS linear-gradient() / radial-gradient() strings, with the same precedence rules react-native-web applies to a static style (two-axis radial position, px for numeric positions, a circle with two different radii degrades to an ellipse), and removes the experimental_backgroundImage: false exclusion.

Browsers decide how the animation looks: current browsers switch background-image discretely even between gradients of the same structure. A transition needs a string backgroundImage in the base style because react-native-web does not accept the object form there.

Test plan

  • Jest: backgroundImage.test.ts (web processor) and animationParser.test.ts.
  • Manual: the Background Image example screen in web-example shows the gradient keyframes switching at the midpoint.

Changelog

Entry added to the Unpublished section of packages/react-native-reanimated/CHANGELOG.md.

Register a web processor that turns the gradient objects React Native
accepts for backgroundImage into CSS gradient functions, so keyframes,
transitions and pseudo-selector styles can carry them on react-native-web.

The serializer spells out both axes of a partial radial position with
React Native's precedence (left over right, top over bottom, 50% for a
missing axis), adds the px unit to numeric color stop positions, renders
a circle with unequal length radii as max(x, y) and a circle with a
percentage radius as the equivalent ellipse, and drops the declaration
instead of emitting "[object Object]" for an object color.
@MatiPl01 MatiPl01 self-assigned this Sep 16, 2026
@coderabbitai

coderabbitai Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

📝 Walkthrough

Walkthrough

The change adds web processing for backgroundImage gradient objects. The processor serializes linear and radial gradients, color stops, positions, sizes, multiple gradients, and numeric colors. The web style configuration registers the processor, and tests cover processor output and CSS keyframe serialization. Documentation and the changelog describe web support. The example route is no longer limited to iOS and Android.

Priority: ⬇️ Low

Change: Feature

Merge Risk: 🟡 Moderate · up to fe282

A valid keyframe that clears backgroundImage can throw while CSS is built, preventing the affected web animation from running. Add the null guard before merging.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the web support added for animating and transitioning backgroundImage gradients, including implementation details and tests.
Title check ✅ Passed The title clearly and concisely identifies the main change: adding web support for CSS animation of backgroundImage gradients.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 38a51a50-2993-4371-a42e-6ef6041e46e7

📥 Commits

Reviewing files that changed from the base of the PR and between 1c21b2e and 08579fb.

📒 Files selected for processing (8)
  • apps/common-app/src/apps/css/examples/animations/routes/properties/base.ts
  • docs/docs-reanimated/docs/guides/supported-properties.mdx
  • packages/react-native-reanimated/CHANGELOG.md
  • packages/react-native-reanimated/src/common/web/style/config.ts
  • packages/react-native-reanimated/src/common/web/style/processors/__tests__/backgroundImage.test.ts
  • packages/react-native-reanimated/src/common/web/style/processors/backgroundImage.ts
  • packages/react-native-reanimated/src/common/web/style/processors/index.ts
  • packages/react-native-reanimated/src/css/web/__tests__/animationParser.test.ts
💤 Files with no reviewable changes (1)
  • apps/common-app/src/apps/css/examples/animations/routes/properties/base.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟠 Major · Guard null before iterating. · backgroundImage.ts:166-181

packages/react-native-reanimated/src/common/web/style/processors/backgroundImage.ts:166-181
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Guard null before iterating. A public Reanimated CSS keyframe can contain backgroundImage: null. Keyframe processing passes it to webPropsBuilder, whose createPropsBuilder skips only undefined. processBackgroundImageWeb then enters its non-string branch and for...of value throws on null instead of omitting the declaration. Add if (value == null) return; before the string check.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: cc6d497d-abef-4abe-ba66-b0d02aec2503

📥 Commits

Reviewing files that changed from the base of the PR and between 08579fb and fe28279.

📒 Files selected for processing (2)
  • packages/react-native-reanimated/src/common/web/style/processors/__tests__/backgroundImage.test.ts
  • packages/react-native-reanimated/src/common/web/style/processors/backgroundImage.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/react-native-reanimated/src/common/web/style/processors/tests/backgroundImage.test.ts
  • packages/react-native-reanimated/src/common/web/style/processors/backgroundImage.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 2 remain after this review.

@MatiPl01

Copy link
Copy Markdown
Contributor Author

Closing: the backgroundImage feature stays in #10193, which will be rebased on the prerequisite fixes; the web serializer fixes from here become commits on that branch.

@MatiPl01 MatiPl01 closed this Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant