In React Native, how does the single-number flex style behave for positive, zero and negative values, and when does flex: 1 fill nothing?
answer
- one number, not three
- positive: grow from a zero basis
- ratios: 1+2+3 makes six parts
- 0 is rigid, -1 shrinks to minimums
- parent needs a size first
basics
~20 sReact Native's flex is one number: a positive value grows in proportion from a zero basis, 0 keeps the view at its width and height, and -1 keeps that size but may shrink to its minimums. flex: 1 fills nothing under an unsized parent.
solid answer
~40 sIn React Native `flex` is a number, not the CSS shorthand. A **positive** value makes the view flexible: it starts from a basis of 0 and grows in proportion to its value, so siblings with `flex: 1`, `2` and `3` get one, two and three sixths of the space. **`0`** makes the view inflexible and sized by its `width` and `height`. **`-1`** sizes it by `width` and `height` too, but lets it shrink down to its `minWidth` or `minHeight` when space runs out. For CSS-like control you set `flexGrow`, `flexShrink` and `flexBasis` directly. The classic failure is `flex: 1` under a parent with no size: the parent measures 0 along the main axis, so there is nothing to fill and the child is invisible.
code
tsx · 22 linesimport { StyleSheet, Text, View } from 'react-native';
export function PlanBands() {
return (
<View style={styles.screen}>
<View style={[styles.band, { flex: 1 }]}>
<Text>Starter</Text>
</View>
<View style={[styles.band, { flex: 2 }]}>
<Text>Team</Text>
</View>
<View style={[styles.band, { flex: 3 }]}>
<Text>Enterprise</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
screen: { flex: 1 },
band: { justifyContent: 'center', padding: 12, borderBottomWidth: 1 },
});go deeper
Recall that flex is one number, that flex: 1 fills remaining space, and that siblings split space by the ratio of their values.
Explain the zero basis behind positive flex, what 0 and -1 do, and why a parent with no size makes flex: 1 collapse.
Diagnose collapsed screens by walking the ancestor chain, and choose between flex and the grow, shrink and basis longhands for each component.
Set conventions for a shared component library: which components own their size and which expect a flexing parent, so screens do not collapse unpredictably.
## One number instead of a shorthand On the web, `flex` is a shorthand for three properties. In React Native, the `flex` style is a **single number** interpreted by **Yoga**, the layout engine that sizes every view. The three longhands, `flexGrow`, `flexShrink` and `flexBasis`, also exist and behave as their names suggest; `flex` is a compact way of choosing one of a few common behaviours. ## What each value means | `flex` value | Behaviour in Yoga | Typical use | |---|---|---| | positive (`1`, `2`, `0.5`) | Flexible: basis 0, grows in proportion to the value | Fill remaining space, split space by ratio | | `0` | Inflexible: sized by `width` and `height` | A fixed header or footer | | `-1` | Sized by `width` and `height`, but may shrink to `minWidth` / `minHeight` when there is not enough space | A panel that should keep its size unless the screen is too small | | not set | Grow 0, shrink 0, basis `auto` | The default for every view | Two details are worth being precise about: - A positive `flex` sets the **basis to 0**, not to the content size. That is why `flex: 1` siblings split space equally regardless of how much content each holds: they all start from zero and share the entire space. - A negative `flex` does not reverse anything or hide the view. It only allows shrinking, and the lower bound is the view's own minimum dimension. ## Ratios with several flexible siblings Suppose a plan-comparison screen divides a 600-point column into three bands with `flex: 1`, `flex: 2` and `flex: 3`: 1. Each band's basis is 0, so the whole 600 points is free space. 2. The total of the flex values is 1 + 2 + 3 = 6. 3. The first band gets 1/6 (100 points), the second 2/6 (200 points), the third 3/6 (300 points). If a sibling has a fixed `height: 120` and no `flex`, it takes its 120 points first and the flexible bands share the rest. Padding on the container and `gap` between children are also subtracted before the split. ## When flex: 1 fills nothing A view can only grow into space its **parent** has. If the parent has no fixed `width` and `height` and no `flex` of its own, its size along the main axis comes from its content, and a child with `flex: 1` has a basis of 0, so the parent measures 0 and the child is invisible. The chain has to hold all the way up: - The screen's outermost `View` usually needs `flex: 1` so that it fills the space the root gives it. - Every intermediate wrapper between that root and the flexible child needs a size or a `flex` too. - A `ScrollView`'s content has no fixed height by design, so `flex: 1` on a child inside the scrolling content does not stretch it to the viewport. When a coloured `View` with `flex: 1` "disappears", walk up the tree and find the first ancestor with no size. ## Debugging a collapsed screen When a screen or panel renders blank, a short routine usually finds it: 1. Give the invisible view a temporary `backgroundColor` and a `borderWidth` to see whether it has any size at all. 2. Walk up one ancestor at a time and do the same, until you reach a view that does have a size. 3. The view just below that one is the culprit: give it `flex: 1` or an explicit size, and the space flows down again. The same routine explains the opposite surprise, a view that is suddenly far too tall: somewhere an ancestor gained `flex: 1` and now fills the whole screen. ## Choosing flex or the longhands - Use `flex: 1` for the common "fill the remaining space" case. - Use `flexGrow: 1` when the view should keep its content size as a basis and then grow, for example a card that must be at least as tall as its text. - Use `flexShrink: 1` when the view should only give back space when crowded, such as a long label in a row. - Use `flexBasis` (a number or percentage) with `flexGrow` for grid-like items that start at a preferred size and share the rest. The TypeScript type of `flex` is `number`, so a CSS habit such as `flex: '1 1 auto'` is caught at compile time rather than failing silently on a device.
- Why do two flex: 1 siblings get equal space even when one holds far more text?A positive `flex` sets each item's basis to 0, so neither starts from its content size. All free space is shared in proportion to the flex values, which are equal. If you want content-sized starting points, use `flexGrow: 1` and leave `flexBasis` at `auto` instead.
- Why does flex: 1 on a child inside a ScrollView not make it fill the screen?A `ScrollView`'s content container has no fixed height along the scroll axis, since it grows to fit its children. A `flex: 1` child starts from a zero basis and has no free space to grow into, so it stays at its minimum. Use the `ScrollView`'s `contentContainerStyle` with `flexGrow: 1` when content should fill the viewport at minimum.
Positive flex values are like splitting a restaurant bill by shares ordered: someone with 2 shares pays twice as much as someone with 1, no matter what they arrived with, because everyone starts from zero.
saying these in an interview costs you the question
- flex: 1 sizes the view to its content, then adds a share of spare space.
- flex: -1 hides the view or reverses its order.
- flex: 1 always fills the screen, whatever the parent's size.
- The flex style accepts a string such as '1 1 auto'.
- A flex: 2 sibling is always twice the size of its content.