flex: 1 does not set flexGrow: 1 #1323

Open
opened 2021-05-10 08:27:06 -07:00 by darkbasic · 9 comments
darkbasic commented 2021-05-10 08:27:06 -07:00 (Migrated from github.com)

Description

Setting the style flex: 1 is supposed to set flexGrow: 1, flexShrink: 1 and flexBasis: "auto".
Apparently it doesn't work because setting flex: 1 produces a different output than flexGrow: 1, flexShrink: 1 and flexBasis: "auto" (see screenshots below).

React Native version:

$ yarn react-native info
yarn run v1.22.10
$ /home/niko/devel/beach/client/node_modules/.bin/react-native info
info Fetching system and libraries information...
System:
    OS: Linux 5.11 Fedora 34 (Workstation Edition) 34 (Workstation Edition)
    CPU: (8) x64 AMD Ryzen 5 2400G with Radeon Vega Graphics
    Memory: 33.34 GB / 62.81 GB
    Shell: 5.1.0 - /bin/bash
  Binaries:
    Node: 12.22.1 - /tmp/yarn--1620659398547-0.22115473234857919/node
    Yarn: 1.22.10 - /tmp/yarn--1620659398547-0.22115473234857919/yarn
    npm: 6.14.13 - ~/.nvm/versions/node/v12.22.1/bin/npm
    Watchman: 0.0.0 - /usr/bin/watchman
  SDKs:
    Android SDK: Not Found
  IDEs:
    Android Studio: Not Found
  Languages:
    Java: Not Found
  npmPackages:
    @react-native-community/cli: Not Found
    react: ~17.0.2 => 17.0.2 
    react-native: 0.64.1 => 0.64.1 
  npmGlobalPackages:
    *react-native*: Not Found
Done in 0.83s.

react-native-elements is at version 3.4.1.

Steps To Reproduce

The view you see in the Flipper screenshots below is the one created by react-native-elements's ListItem.Content, which applies the styles in styles.container to its children View (which gets automatically created):

}) => {
  return (
    <ListItem bottomDivider>
      <ListItem.Content style={styles.container}>
        <Everythingelse />
      </ListItem.Content>
    </ListItem>
  );
};

export const ITEM_HEIGHT = 130;

const styles = StyleSheet.create({
  container: {
    height: ITEM_HEIGHT,
    flexGrow: 1,
    flexShrink: 1,
    flexBasis: 'auto',
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'stretch',
  },

react-native-elements's ListItem.Content also applies flex: 1 to its automatically created children View, but despite that if I omit flexGrow: 1 in styles.container the layout breaks. That means that the shorthand flex: 1 somehow does not set flexGrow: 1.

Expected Results

flex: 1 should automatically set flexGrow: 1, flexShrink: 1 and flexBasis: "auto". It shouldn't be necessary to manually set flexGrow: 1.

flexGrow: 1 + flexShrink: 1 + flexBasis: "auto":
flexGrow

flex: 1:
flex

## Description Setting the style `flex: 1` is supposed to set `flexGrow: 1`, `flexShrink: 1` and `flexBasis: "auto"`. Apparently it doesn't work because setting `flex: 1` produces a different output than `flexGrow: 1`, `flexShrink: 1` and `flexBasis: "auto"` (see screenshots below). ## React Native version: ``` $ yarn react-native info yarn run v1.22.10 $ /home/niko/devel/beach/client/node_modules/.bin/react-native info info Fetching system and libraries information... System: OS: Linux 5.11 Fedora 34 (Workstation Edition) 34 (Workstation Edition) CPU: (8) x64 AMD Ryzen 5 2400G with Radeon Vega Graphics Memory: 33.34 GB / 62.81 GB Shell: 5.1.0 - /bin/bash Binaries: Node: 12.22.1 - /tmp/yarn--1620659398547-0.22115473234857919/node Yarn: 1.22.10 - /tmp/yarn--1620659398547-0.22115473234857919/yarn npm: 6.14.13 - ~/.nvm/versions/node/v12.22.1/bin/npm Watchman: 0.0.0 - /usr/bin/watchman SDKs: Android SDK: Not Found IDEs: Android Studio: Not Found Languages: Java: Not Found npmPackages: @react-native-community/cli: Not Found react: ~17.0.2 => 17.0.2 react-native: 0.64.1 => 0.64.1 npmGlobalPackages: *react-native*: Not Found Done in 0.83s. ``` `react-native-elements` is at version 3.4.1. ## Steps To Reproduce The view you see in the Flipper screenshots below is the one created by `react-native-elements`'s `ListItem.Content`, which applies the styles in `styles.container` to its children `View` (which gets automatically created): ``` }) => { return ( <ListItem bottomDivider> <ListItem.Content style={styles.container}> <Everythingelse /> </ListItem.Content> </ListItem> ); }; export const ITEM_HEIGHT = 130; const styles = StyleSheet.create({ container: { height: ITEM_HEIGHT, flexGrow: 1, flexShrink: 1, flexBasis: 'auto', display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'stretch', }, ``` `react-native-elements`'s `ListItem.Content` also applies `flex: 1` to its automatically created children `View`, but despite that if I omit `flexGrow: 1` in `styles.container` the layout breaks. That means that the shorthand `flex: 1` somehow does not set `flexGrow: 1`. ## Expected Results `flex: 1` should automatically set `flexGrow: 1`, `flexShrink: 1` and `flexBasis: "auto"`. It shouldn't be necessary to manually set `flexGrow: 1`. ## Snack, code example, screenshot, or link to a repository: `flexGrow: 1` + `flexShrink: 1` + `flexBasis: "auto"`: ![flexGrow](https://user-images.githubusercontent.com/1047358/117681402-5d260580-b1b2-11eb-80ab-4ebfc36bb382.png) `flex: 1`: ![flex](https://user-images.githubusercontent.com/1047358/117681447-67480400-b1b2-11eb-9cb4-67b3bcb45997.png)
ecreeth commented 2021-05-12 11:15:11 -07:00 (Migrated from github.com)

Setting the style flex: 1 is supposed to set flexGrow: 1, flexShrink: 1 and flexBasis: "auto".

image

>Setting the style [flex](https://reactnative.dev/docs/layout-props#flex): 1 is supposed to set flexGrow: 1, flexShrink: 1 and flexBasis: "auto". ![image](https://user-images.githubusercontent.com/20761166/118023977-25db6400-b32c-11eb-96bc-963c4c83d594.png)
darkbasic commented 2021-05-13 03:35:36 -07:00 (Migrated from github.com)

@ecreeth flex: 1 doesn't set flexGrow: 1, flexShrink: 1, flexBasis: 0 either, because flexGrow: 1, flexShrink: 1, flexBasis: 0 renders correctly (see screenshot below) while flex: 1 doesn't (see previous screenshot).

react native flex basis 0

@ecreeth `flex: 1` doesn't set `flexGrow: 1, flexShrink: 1, flexBasis: 0` either, because `flexGrow: 1, flexShrink: 1, flexBasis: 0` renders correctly (see screenshot below) while `flex: 1` doesn't (see previous screenshot). ![react native flex basis 0](https://user-images.githubusercontent.com/1047358/118114314-b3c85500-b3e7-11eb-8377-d8fd17e88779.png)
mxcihak commented 2021-08-17 07:11:19 -07:00 (Migrated from github.com)

Same here. For me this happens when I set container to flex: 1 (everything OK) then to flexGrow: 1 (everything OK) then to flex:1 (container disappears - height: 0)

Same here. For me this happens when I set container to flex: 1 (everything OK) then to flexGrow: 1 (everything OK) then to flex:1 (container disappears - height: 0)
darkbasic commented 2021-08-18 02:09:42 -07:00 (Migrated from github.com)

I'm not sure but I think it might be a react-native regression, if I recall correctly I've tried to downgrade several major versions and the issue disappeared. In the end I've decided to simply change my CSS because it was easier than debugging it.

I'm not sure but I think it might be a react-native regression, if I recall correctly I've tried to downgrade several major versions and the issue disappeared. In the end I've decided to simply change my CSS because it was easier than debugging it.
dharit-tan commented 2023-05-04 14:54:28 -07:00 (Migrated from github.com)

Bump, seeing this as well!

Bump, seeing this as well!
matart15 commented 2023-07-05 06:01:08 -07:00 (Migrated from github.com)

exact same.
and this issue is closed without explanation
https://github.com/facebook/react-native/issues/11565

exact same. and this issue is closed without explanation https://github.com/facebook/react-native/issues/11565
lunaleaps commented 2023-07-05 12:29:21 -07:00 (Migrated from github.com)

Can we move this issue to the yoga repo?
cc @NickGerleman

Can we move this issue to the yoga repo? cc @NickGerleman
NickGerleman commented 2023-12-16 00:11:07 -08:00 (Migrated from github.com)

https://developer.mozilla.org/en-US/docs/Web/CSS/flex

One-value syntax: the value must be one of:

  1. a valid value for : then the shorthand expands to flex: <flex-grow> 1 0.
  2. a valid value for : then the shorthand expands to flex: 1 1 <flex-basis>.

So, on the web, the number should lead to:

  1. Flex shrink being set to 1
  2. Flex grow getting set to n if it is a number, or 1 if it is a length
  3. Flex basis is set to n if it is a length, or 0 if it is a number

I confirmed this by looking at https://www.w3.org/TR/css-flexbox-1/#flex-common

The React Native/Yoga version of flex is documented here, and I checked that it is how the code works. The value for flex will contribute to flexGrow if positive, and flexShrink if negative. https://reactnative.dev/docs/layout-props#flex

62f47190fb from a few years ago has Yoga doing the right thing when opted into useWebDefaults (but I think actually doing the wrong thing wrt flexbasis should be set to zero). But changing these defaults for existing RN styles would be pretty breaking.

https://developer.mozilla.org/en-US/docs/Web/CSS/flex > One-value syntax: the value must be one of: > 1. a valid value for [<flex-grow>](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow): then the shorthand expands to `flex: <flex-grow> 1 0`. > 2. a valid value for [<flex-basis>](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-basis): then the shorthand expands to `flex: 1 1 <flex-basis>`. So, on the web, the number should lead to: 1. Flex shrink being set to 1 2. Flex grow getting set to `n` if it is a number, or `1` if it is a length 3. Flex basis is set to `n` if it is a length, or `0` if it is a number I confirmed this by looking at https://www.w3.org/TR/css-flexbox-1/#flex-common The React Native/Yoga version of flex is documented here, and I checked that it is how the code works. The value for flex will contribute to `flexGrow` if positive, and `flexShrink` if negative. https://reactnative.dev/docs/layout-props#flex https://github.com/facebook/yoga/commit/62f47190fb2c13d47b13efacfc237f30ab312b51 from a few years ago has Yoga doing the right thing when opted into `useWebDefaults` (but I think actually doing the wrong thing wrt flexbasis should be set to zero). But changing these defaults for existing RN styles would be pretty breaking.
darkbasic commented 2023-12-16 00:22:45 -08:00 (Migrated from github.com)

If this is indeed the case, nice catch! Breaking or not the current defaults make little sense and are pretty annoying and confusing.

If this is indeed the case, nice catch! Breaking or not the current defaults make little sense and are pretty annoying and confusing.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DaddyFrosty/yoga#1323
No description provided.