# Keyboard does not cover input fields (KeyboardAvoidingView used)

- **Pattern:** `ab-001972` (`mobile-ux-patterns.keyboard-input.keyboard-avoiding`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001972
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001972)

## Why it matters

When the keyboard opens and covers the active `TextInput`, users type blind — they cannot see validation errors, cannot confirm the autofill suggestion, and often submit the wrong value. Login and signup screens are the worst offenders because the password field is typically the last field and therefore the lowest on screen. Field-blind submission produces silent wrong-password lockouts that users attribute to the app, not the covered field.

## Severity rationale

High because keyboard occlusion blocks the primary interaction on forms, which are the conversion path.

## Remediation

Wrap every form in `KeyboardAvoidingView` with platform-correct behavior, and use `keyboardShouldPersistTaps="handled"` on any `ScrollView` containing inputs:

```tsx
import { KeyboardAvoidingView, Platform } from 'react-native';
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={{ flex: 1 }}>
  <TextInput placeholder="Email" />
  <TextInput placeholder="Password" secureTextEntry />
  <Button title="Sign In" onPress={submit} />
</KeyboardAvoidingView>
```

## Detection

- **ID:** `keyboard-avoiding`
- **Severity:** `high`
- **What to look for:** Count all screens with TextInput fields. For each screen, check whether `KeyboardAvoidingView` wraps the form, or whether the ScrollView uses `keyboardShouldPersistTaps` and `contentInset`. Report: "X of Y screens with inputs have keyboard avoidance."
- **Pass criteria:** At least 100% of screens with TextInput fields use `KeyboardAvoidingView` (with `behavior` set to `"padding"` on iOS, `"height"` on Android) or equivalent keyboard-aware scrolling. Input fields remain visible when keyboard appears.
- **Fail criteria:** Any screen with TextInput fields lacks keyboard avoidance — keyboard covers input fields, making it impossible to see what is being typed. Do NOT pass when `KeyboardAvoidingView` is present but the `behavior` prop is missing or incorrect for the platform.
- **Skip (N/A) when:** App has no text input fields (e.g., content-only display app with no forms or search).
- **Detail on fail:** Name the screen and quote its layout structure. `"Login screen has no KeyboardAvoidingView — keyboard covers the password input and submit button."` or `"TextInput fields in form are behind keyboard on some devices."`
- **Remediation:** Use KeyboardAvoidingView to lift content:

  ```tsx
  import { KeyboardAvoidingView, Platform } from 'react-native';

  <KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={{ flex: 1 }}>
    <View>
      <TextInput placeholder="Email" />
      <TextInput placeholder="Password" />
      <Button title="Sign In" />
    </View>
  </KeyboardAvoidingView>
  ```

  Or configure ScrollView for keyboard persistence:

  ```tsx
  <ScrollView keyboardShouldPersistTaps="handled" contentInsetAdjustmentBehavior="automatic">
    {/* Form fields */}
  </ScrollView>
  ```

Taxons: user-experience

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