Reject percentage radius for circle radial gradients - #57874
Open
Titozzz wants to merge 2 commits into
Open
Conversation
In processBackgroundImage, the explicit-size branch shifts the next token
to look for a second size value and discards it when it is not a length or
percentage. When that token is 'at', the whole position clause is lost:
the position defaults back to center and the position values are then
re-parsed as a new size, silently overriding the declared one.
radial-gradient(circle 100px at 25% 75%, red, blue) previously parsed as
size {x: '25%', y: '75%'} with position {top: '50%', left: '50%'};
it now parses as size {x: 100, y: 100} with position {left: '25%', top: '75%'}.
The existing test for this syntax only used 'at center', which is
indistinguishable from the default position, so the bug was invisible.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per the CSS spec (css-images-3, <radial-size>), a circle's explicit radius must be a <length> - percentages are only valid for ellipses. Browsers reject the whole declaration for values such as radial-gradient(circle 50%, red, blue), while React Native accepted them and rendered an arbitrary interpretation (max of both resolved axes), so the same style silently diverged between native and web. processBackgroundImage now returns no gradient for a circle (explicit or inferred from a single size) whose size is a percentage, matching web behavior. Ellipses with percentage sizes are unaffected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Titozzz
marked this pull request as ready for review
August 10, 2026 12:29
Titozzz
pushed a commit
to Titozzz/react-native-reanimated
that referenced
this pull request
Aug 10, 2026
Ports the two upstream react-native processBackgroundImage changes (react/react-native#57873 and react/react-native#57874) into the backgroundImage processor to keep both parsers in sync: - #57873 (position dropped after an explicit size) was already fixed here; align the code comment with upstream and use a px-sized circle in the regression test - #57874: reject a percentage radius for circle radial gradients (explicit 'circle 50%' and the inferred circle from a single '50%' size). Per the CSS spec a circle radius must be a <length>; percentages remain valid for ellipse sizes Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011p2PjxNunbHriH5853qssK
cipolleschi
approved these changes
Aug 10, 2026
|
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this in D115426055. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
Stacked on #57873 (its commit is included here). Without that fix,
circle <length> at <position>strings would mis-parse into percentage sizes and be wrongly rejected by this validation.Summary:
Per css-images-3
<radial-size>, a circle's explicit radius must be a<length>— percentages are only valid for ellipses. Browsers reject the whole declaration for values likeradial-gradient(circle 50%, red, blue)(computedbackground-image: none), while React Native accepted them and rendered an arbitrary interpretation (maxof the value resolved against width and against height). The same style string therefore silently diverged between native and web, contradicting the "Same as web" validation policy this parser already follows for other invalid values.processBackgroundImagenow returns no gradient when a circle — explicit (circle 50%) or inferred from a single size (radial-gradient(50%, ...), which browsers also reject) — has a percentage size. Ellipses with percentage sizes (50% 20%) are unaffected.Note: the structured C++ parser in
react/renderer/css/CSSBackgroundImage.hhas the same leniency (CSSRadialGradientExplicitSizeaccepts<length-percentage>for both axes regardless of shape) and could get the same validation as a follow-up.Changelog:
[GENERAL] [FIXED] - Reject percentage radii for circle radial gradients, matching web behavior
Test Plan:
Added three Fantom tests in
processBackgroundImage-itest.js:circle 50%rejected, inferred-circle50%rejected, ellipse50% 20%still accepted.Verified the accept/reject matrix against Chrome (
getComputedStyle(...).backgroundImage === 'none'for rejected values):radial-gradient(circle 50%, red, blue)radial-gradient(50%, red, blue)radial-gradient(50% 20%, red, blue)radial-gradient(circle 100px, red, blue)🤖 Generated with Claude Code