react / react/yoga

Incorrect width calculations when using margin with align-items: 'stretch'

Open
#1,788 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
18.9k
Forks
1.6k
Avg merge
1m
Merged PRs (30d)
1

Description

Description

When using a View with margin inside a parent View that has alignItems: 'stretch', the child's width is incorrectly calculated. The margin appears to be subtracted multiple times from the available width, making the child View significantly narrower than expected.

Expected behaviour

Given a parent View of width 400 and a child View with margin: 20:

  • Child width should be: 360 (parent width - margin * 2)
  • The margin of 20 should only be subtracted twice (left and right)
Steps to reproduce
  1. Create a minimal React Native app with this component:
import React from 'react';
import { Dimensions, View } from 'react-native';

function App(): React.JSX.Element {
  const size = Dimensions.get('window');
  return (
    <View
      style={{
        backgroundColor: 'red',
        width: size.width,
        height: size.height,
        alignItems: 'center',
        justifyContent: 'center',
      }}>
      <View
        style={{
          backgroundColor: 'blue',
          aspectRatio: 16 / 9,
          alignSelf: 'stretch',
          margin: 24,
        }}
      />
    </View>
  );
}

export default App;

  1. Notice how width of child View is significantly narrower than expected.
React Native Version

0.77.1

Affected Platforms

Runtime - iOS

Output of npx @react-native-community/cli info
System:
  OS: macOS 15.1.1
  CPU: (12) arm64 Apple M3 Pro
  Memory: 683.89 MB / 36.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.13.1
    path: ~/.nvm/versions/node/v20.13.1/bin/node
  Yarn: Not Found
  npm:
    version: 10.8.1
    path: ~/.nvm/versions/node/v20.13.1/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.16.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.0
      - iOS 18.0
      - macOS 15.0
      - tvOS 18.0
      - visionOS 2.0
      - watchOS 11.0
  Android SDK: Not Found
IDEs:
  Android Studio: 2024.2 AI-242.23726.103.2422.12816248
  Xcode:
    version: 16.0/16A242d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.14
    path: /opt/homebrew/opt/openjdk@17/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.1
    wanted: 15.0.1
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.77.1
    wanted: 0.77.1
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true
Stacktrace or Logs
Reproducer

https://github.com/LJNGDAHL/layout-bug

Screenshots and Videos
screenshot showing the issue

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked minimal React Native reproducer and inspect Yoga's layout handling for a stretched child with margin and aspectRatio. Reproduce the reported narrowing on iOS, then verify that a parent width of 400 and margin of 20 produce a child width of 360 without repeated margin subtraction.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, react-native
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.