A React Native boarding-pass screen clips and overlaps at the largest system text size; how do you find and fix the causes?
answer
- fixed heights clip, minHeight grows
- numberOfLines truncates essential data
- rows must wrap or stack
- the screen must scroll
- test the largest accessibility size on devices
basics
~20 sReproduce it on devices at the largest text setting, then remove the fixed constraints: minHeight instead of height, no truncation of essential data, rows that wrap or stack, a scrolling screen, and caps only on already-large display text.
solid answer
~40 sI first reproduce it on real iOS and Android devices at the largest accessibility text size, not the default, and walk every state of the pass: long passenger names, a delay banner, a gate change. The usual causes are fixed `height` on cards and rows, `numberOfLines={1}` truncating a name or seat, label-and-value pairs locked side by side in a `flexDirection: 'row'`, absolute positioning, and a screen that cannot scroll. The fixes are `minHeight` instead of `height`, letting essential text wrap, `flexWrap: 'wrap'` or a stacked layout when the font scale is large, a `ScrollView` around the content, and a `maxFontSizeMultiplier` only on display text such as the gate number. The barcode stays a fixed size because it is scanned, not read. Turning off scaling is not a fix.
code
tsx · 26 linesimport {ScrollView, StyleSheet, Text, View} from 'react-native';
type Field = {label: string; value: string};
export function PassDetails({fields}: {fields: Field[]}) {
return (
<ScrollView contentContainerStyle={styles.content}>
<View style={styles.grid}>
{fields.map(field => (
<View key={field.label} style={styles.cell}>
<Text style={styles.label}>{field.label}</Text>
<Text style={styles.value}>{field.value}</Text>
</View>
))}
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
content: {padding: 16},
grid: {flexDirection: 'row', flexWrap: 'wrap', gap: 16},
cell: {minWidth: 120, flexGrow: 1},
label: {fontSize: 14},
value: {fontSize: 20, fontWeight: '600'},
});go deeper
Recall that fixed heights and single-line truncation are what break first at large text sizes, and that the screen may need to scroll.
Explain how minHeight, wrapping, flexWrap and ScrollView each remove a fixed assumption, and where a maxFontSizeMultiplier cap is acceptable.
Show a reproducible device pass at the largest sizes on both platforms, a prioritised fix list, and how you argue against disabling scaling to meet a design.
Build the large-text check into how screens are designed and reviewed, so layouts are specified with growth rules rather than fixed heights.
## Why the largest size breaks screens React Native scales `Text` with the user's system text size by default. At the default setting a boarding pass fits on one screen; at the largest **accessibility** sizes the same text can be two or three times its default size, depending on the platform. Every constraint that assumed a text height, a fixed card height, a single line, a row that fits side by side, fails at once. The fix is to find those assumptions and replace them with layouts that grow. ## Reproducing it properly 1. **Use real devices on both platforms** with the largest text setting the system offers, including iOS's larger accessibility sizes. A simulator with the default size proves nothing. 2. **Walk every state**, not just the happy path: a long passenger name, a two-line destination, a delay banner, a gate change, the offline banner. 3. **Rotate and try smaller devices**, where the space runs out first. 4. **Read the screen as the user would**: is every piece of information still visible, in order, without overlap? ## The usual causes | Cause | Symptom at large text | Fix | |---|---|---| | fixed `height` on a card or row | text clipped at the bottom | `minHeight`, or no height at all | | `numberOfLines={1}` on essential data | passenger name or seat shows an ellipsis | allow wrapping, or more lines | | label and value side by side in a row | value squeezed or overlapping | `flexWrap: 'wrap'`, or stack into a column when the scale is large | | `position: 'absolute'` for text | text overlaps other elements | keep text in flow and lay it out with flex | | screen without a `ScrollView` | bottom content pushed off screen | scroll the content | | icons sized next to text | tiny icon beside huge text | size icons from the text or accept the contrast | ## Fixes that keep the user's choice - **Let containers grow.** Replace `height` with `minHeight`, and avoid fixed heights on anything containing text. - **Let text wrap.** Keep `numberOfLines` for secondary text such as a marketing line, never for the passenger name, flight number, seat or boarding time. - **Let rows reflow.** A three-column grid of flight details can use `flexWrap: 'wrap'` with a `minWidth` on each cell, so cells drop to new lines as text grows. For very large scales, switch the grid to a single column. - **Let the screen scroll.** A boarding pass is one screen visually, but at large text it must scroll; wrap the content in a `ScrollView`. - **Cap only display text.** A gate number that is already 48 points can carry `maxFontSizeMultiplier` of around 1.5; body data stays uncapped. - **Leave the barcode alone.** The scannable code is not text; keep it at a fixed, scannable size and give it its own space above or below the details. ## What not to do - Setting `allowFontScaling={false}` on the screen. The layout stops breaking because the user's setting is ignored; the people who needed large text are the ones who lose. - Capping all text at a low multiplier to fit the original design. - Shrinking text back with `adjustsFontSizeToFit` on body data, which undoes the user's choice with extra steps. ## Keeping it fixed A large-text pass belongs in the definition of a screen being finished: check the new screen at the largest setting on both platforms before release. A screenshot at the largest size next to the default one in a pull request makes regressions visible to reviewers.
- The designer insists the boarding pass must fit on one screen without scrolling. How do you respond?At the default text size it can; at the largest accessibility sizes it cannot without shrinking or hiding the information the user asked to see larger. I agree to the one-screen layout as the default and make the content scroll when it no longer fits, keeping the barcode reachable, and show both states in the design review.
- Why keep numberOfLines on some text but not on the passenger name?Truncation hides information. For decorative or secondary text, an ellipsis at large sizes is acceptable. The passenger name, flight, seat and boarding time are what the pass is for, and at large sizes an ellipsis can hide exactly the characters the gate agent or the traveller needs, so that text must wrap.
saying these in an interview costs you the question
- Testing the default text size on a simulator is enough for a text-scaling check.
- allowFontScaling={false} on the screen is an acceptable fix for clipping at large sizes.
- A boarding pass should never scroll, even at the largest text size.
- numberOfLines={1} is safe on a passenger name because names are short.
- The barcode should scale with the text size to stay proportional.