# Layout responds correctly to all supported screen sizes

- **Pattern:** `ab-001962` (`mobile-ux-patterns.layout-safe-areas.responsive-layout`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001962
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001962)

## Why it matters

Hardcoding widths above 320pt cuts off content on iPhone SE and any small-screen Android — users see clipped headlines, overlapping buttons, and horizontal scroll on what should be a vertical feed. On the large end, 430pt+ devices get awkwardly stretched layouts with orphaned white space. The App Store SE-class device tests and Google Play pre-launch reports both flag these as blocking issues, and review screenshots fail silently when text overflows.

## Severity rationale

Critical because content cut off on the smallest supported device makes features functionally unreachable.

## Remediation

Replace every fixed width with flex sizing and read viewport dimensions via `useWindowDimensions` to branch layout at breakpoints:

```tsx
import { useWindowDimensions } from 'react-native';
function Screen() {
  const { width } = useWindowDimensions();
  const cols = width > 600 ? 3 : 2;
  return <FlatList numColumns={cols} key={cols} data={items} renderItem={renderItem} />;
}
```

Pass `key={cols}` so the list remounts when the column count changes.

## Detection

- **ID:** `responsive-layout`
- **Severity:** `critical`
- **What to look for:** Examine screen designs for at least 3 device widths: small (320-375pt, iPhone SE), medium (390pt, iPhone 14), large (430pt+, iPhone 14 Plus/tablet). Count all fixed-width containers and check whether any exceed the smallest supported width.
- **Pass criteria:** Layout is responsive to device width variations using flex-based or percentage-based sizing. No content is cut off or requires horizontal scrolling on portrait phones at 320pt width. No fixed-width containers exceed 320pt. Text is readable on all screen sizes.
- **Fail criteria:** Layout breaks on small or large screens. Content is cut off, text is too small to read, or horizontal scrolling is required. Any fixed-width container exceeds 320pt.
- **Skip (N/A) when:** The app is portrait-only and targets a single known device width (extremely rare for public apps).
- **Detail on fail:** Identify screens that break. Quote the actual width values found. Example: `"Header text is cut off on iPhone SE (375pt width). Tab bar labels wrap awkwardly on iPhone 14 Plus (430pt width)."` or `"FlatList items are fixed width (320pt) causing overflow on large screens."`
- **Remediation:** Use Dimensions API or `useWindowDimensions` hook for responsive design:

  ```tsx
  import { useWindowDimensions } from 'react-native';

  function ResponsiveScreen() {
    const { width } = useWindowDimensions();
    const itemsPerRow = width > 600 ? 3 : 2;

    return (
      <FlatList
        data={items}
        numColumns={itemsPerRow}
        renderItem={({ item }) => <Item />}
        key={itemsPerRow}
      />
    );
  }
  ```

  Use flex-based layouts instead of fixed widths:

  ```tsx
  <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
    <View style={{ flex: 1, marginRight: 8 }}>{/* Left column */}</View>
    <View style={{ flex: 1 }}>{/* Right column */}</View>
  </View>
  ```

Taxons: user-experience

HTML version: https://auditbuffet.com/patterns/ab-001962
