Add max-content support for width, height, and flex-basis - #2012
Open
intergalacticspacehighway wants to merge 1 commit into
Open
Add max-content support for width, height, and flex-basis#2012intergalacticspacehighway wants to merge 1 commit into
max-content support for width, height, and flex-basis#2012intergalacticspacehighway wants to merge 1 commit into
Conversation
Implements the CSS max-content sizing keyword (css-sizing-3) for dimensions and flex-basis. The public setters existed but layout treated the keyword as auto; this makes them take effect. Keyword axes are measured with indefinite available space, then laid out at the measured (min/max clamped) size, so descendants resolve percentages against the resolved value and wrap within it. Covers root constraint minting (including a second height measure when a width clamp changes wrapping), the flex-basis cascade, the cross-axis path, the stretch re-layout guards, and absolute layout. Aspect-ratio transfer from a resolved keyword axis is deferred; the browser target is recorded in a disabled fixture case and the current behavior is pinned by MaxContentAspectRatioTest. Root cases that need a definite owner size are hand-written (gentest cannot express one).
intergalacticspacehighway
force-pushed
the
css-max-content-dimensions
branch
from
August 27, 2026 04:58
625839c to
7f0002f
Compare
3 tasks
intergalacticspacehighway
added a commit
to expo/expo
that referenced
this pull request
Aug 31, 2026
# Why Fixes - #47883, #48059 Fixes the layout loops that happens in some cases when `Host` and `RNHostView` has `matchContents` and child of `RNHostView` depends upon parent on sizing. Explained it in more detail here - #48059 (comment) <!-- Please describe the motivation for this PR, and link to relevant GitHub issues, forums posts, or feature requests. --> # How Set `RNHostView` node as a leaf and measurable node using shadow node traits. This removes it from the yoga layout hierarchy (shadow node hierarchy is still preserved). Override `measureContent` and `layout` shadow node functions for `RNHostView`. The `measureContent` is called by Yoga during layout and `layout` is called during commit. A better fix would be if Yoga supports `max-content` so we could just do `<RNHostView style={{ width: "max-content", height: "max-content" }} />` if someone passes `matchContents`. Made a PR in Yoga for that react/yoga#2012 <!-- How did you build this feature or fix this bug and why? --> # Test Plan Added regression testcases for RNHostView which leads to loops. <!-- Please describe how you tested this change and how a reviewer could reproduce your test, especially if this PR does not include automated tests! If possible, please also provide terminal output and/or screenshots demonstrating your test/reproduction. --> # Checklist <!-- Please check the appropriate items below if they apply to your diff. --> - [ ] I added a `changelog.md` entry and rebuilt the package sources according to [this short guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting) - [ ] This diff will work correctly for `npx expo prebuild` & EAS Build (eg: updated a module plugin). - [ ] Conforms with the [Documentation Writing Style Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
intergalacticspacehighway
added a commit
to expo/expo
that referenced
this pull request
Aug 31, 2026
Fixes - #47883, #48059 Fixes the layout loops that happens in some cases when `Host` and `RNHostView` has `matchContents` and child of `RNHostView` depends upon parent on sizing. Explained it in more detail here - #48059 (comment) <!-- Please describe the motivation for this PR, and link to relevant GitHub issues, forums posts, or feature requests. --> Set `RNHostView` node as a leaf and measurable node using shadow node traits. This removes it from the yoga layout hierarchy (shadow node hierarchy is still preserved). Override `measureContent` and `layout` shadow node functions for `RNHostView`. The `measureContent` is called by Yoga during layout and `layout` is called during commit. A better fix would be if Yoga supports `max-content` so we could just do `<RNHostView style={{ width: "max-content", height: "max-content" }} />` if someone passes `matchContents`. Made a PR in Yoga for that react/yoga#2012 <!-- How did you build this feature or fix this bug and why? --> Added regression testcases for RNHostView which leads to loops. <!-- Please describe how you tested this change and how a reviewer could reproduce your test, especially if this PR does not include automated tests! If possible, please also provide terminal output and/or screenshots demonstrating your test/reproduction. --> <!-- Please check the appropriate items below if they apply to your diff. --> - [ ] I added a `changelog.md` entry and rebuilt the package sources according to [this short guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting) - [ ] This diff will work correctly for `npx expo prebuild` & EAS Build (eg: updated a module plugin). - [ ] Conforms with the [Documentation Writing Style Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md) Backport notes: - The `apps/test-suite` regression tests are omitted. On sdk-57 `apps/test-suite` has no `@expo/ui` dependency and its `types.ts` lacks `JasmineInterface` and `TestPortal`, so the new suite needs two unrelated prerequisite commits plus a lockfile change. The native fix, the docs note and the changelog entries are backported as-is. - The `docs/pages/versions/v57.0.0/sdk/ui/**/rnhostview.mdx` hunks are dropped. Those files do not exist on sdk-57; `docs/pages/versions/unversioned` is the live SDK 57 docs here. - Rebuilt `packages/expo-ui/build` because `build/` is tracked on release branches. (cherry picked from commit 97baf3b)
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.
Why
Implements the CSS
max-contentsizing keyword forwidth,height, andflex-basis.The public setter (
YGNodeStyleSetWidthMaxContent) already exist, but layout silently treated the keyword asauto. This PR makes them take effect.We have a feature in Expo UI (RNHostView) that allows mounting a React Native hierarchy inside a SwiftUI hierarchy and allowing it to grow to it's natural size. So
max-contentwould be very useful in that case (autosizes are context dependent and often depend on parent dimensions)How
The
max-contentallows content to be laid out to it's intrinsic size, given an indefinite space in an axis. It requires changes to root, flex-basis, cross-axis (prevent stretch) and absolute layout path.Testing
Test includes browser generated
max-contentspec which aims to test all the control flow that is added in this PR and also some tests (specifying max-content to owner size) which is not supported by gentest yet.TODOs
min-width: max-content,max-width: max-contentnot supported yet.max-contentaxis yet (browsers do this). Documented in the disabledmax_content_with_aspect_ratiofixture case and pinned byMaxContentAspectRatioTest. Currently aspect ratio needs some work to make it spec compliant, it has the same issue when child has percentage dimensions.