Mobile App Design
Intro
Mobile UX is shaped by finger-sized touch targets, one-thumb reach,
platform conventions, and flaky connectivity. Start with the smallest
supported screen, respect platform idioms for navigation and
components, and design for offline-first use from the beginning.
Overview
Touch target sizing
- Minimum 44x44 points (iOS) / 48x48 dp (Android) for all
interactive elements.
- At least 8pt gap between targets to prevent mis-taps.
- Primary CTAs 48-56pt high.
- Thumbs reach the lower two-thirds of the screen easily — put
frequent actions there.
- Keep destructive actions away from frequent-tap zones.
- Floating action buttons: 56dp standard, 40dp mini.
Navigation patterns
- Tab bar (bottom): 3-5 top-level destinations, always visible,
best for peer sections.
- Navigation drawer (hamburger): 5+ destinations or infrequent
sections.
- Stack navigation: push/pop for hierarchical detail screens.
- Modal sheets: temporary tasks, filters, confirmations —
dismiss with swipe or button.
Keep depth shallow (3 levels max). Show a back button or
swipe-to-go-back gesture on every non-root screen. Persistent bottom
nav should highlight the active tab and not reset tab state on
re-tap.
Responsive layouts
Design for the smallest supported screen first (375pt width for iOS,
360dp for Android). Use a 4pt or 8pt spacing grid. Support landscape
unless the content is strongly portrait-oriented. Adapt to tablets
with split-view or increased content width via max-width constraints.
Support Dynamic Type (iOS) and font scaling (Android) — never
hardcode font sizes — and test with the system font set to its
maximum size to catch overflow.
iOS vs Android conventions
- Back navigation: iOS swipe-from-edge or top-left button;
Android system back button or gesture.
- Tabs: iOS bottom tab bar; Android bottom navigation bar or top
tabs.
- Buttons: iOS plain text or rounded rect; Android filled or
outlined Material buttons.
- Alerts: iOS centered alerts with stacked buttons; Android
dialogs with side-by-side buttons.
- Typography: iOS uses SF Pro; Android uses Roboto or system
font.
- Icons: iOS SF Symbols (outline by default); Android Material
Icons (filled or outlined).
When in doubt, follow platform conventions — users expect familiar
behavior.
Gesture patterns
- Tap: primary interaction — feedback under 100ms.
- Long press: secondary actions, context menus — always provide
a visible alternative.
- Swipe: list actions (delete, archive), sheet dismissal, page
navigation.
- Pull to refresh: standard for list content — show a spinner.
- Pinch to zoom: images, maps — provide zoom controls as an
alternative.
Make swipe actions discoverable with a peek animation on first use.
Never make gestures the only way to perform an action.
Accessibility
Support screen readers with labels on every interactive element and
image. Maintain 4.5:1 text contrast, 3:1 UI contrast. Support Dynamic
Type and font scaling without layout breakage. Provide captions or
transcripts for audio/video. Test with VoiceOver (iOS) and TalkBack
(Android). Ensure touch targets stay accessible at all accessibility
zoom levels. Respect reduced-motion preferences with static
alternatives.
Offline-first design
- Show cached content immediately while fetching updates in the
background.
- Display clear "offline" indicators — never silently fail.
- Queue user actions when offline and sync when reconnected.
- Use optimistic UI: show the result immediately, reconcile later.
- Store critical data locally — users expect apps to work without
signal.
- Design conflict resolution for collaborative data.
Push notifications
- Request permission at a contextually relevant moment, not on first
launch.
- Explain the value before asking ("Get notified when your order
ships").
- Group related notifications to avoid overwhelming the user.
- Deep link from notifications directly to the relevant content.
- Respect notification settings — provide in-app controls to
customize.
- Never use notifications for marketing on first install — earn
trust first.
Onboarding flows
- Keep onboarding to 3-5 screens maximum — users want to use the
app.
- Show value immediately — let users explore before requiring
sign-up.
- Progressive disclosure: teach features as users encounter them.
- Skip onboarding for returning users by checking for existing data.
- Provide a "Skip" option on every onboarding screen.
- Prefer contextual tooltips and coach marks over upfront tutorials.
Gotchas
Agent-specific failure modes — provider-neutral pause-and-self-check items:
- Designing for the largest screen first and scaling down. Starting with a wide screen allows fitting too much content, which breaks on the common 375pt iPhone viewport. Design for the smallest supported screen first, then progressively enhance for larger displays.
- Using touch targets smaller than platform minimums. Anything below 44×44 points (iOS) or 48×48 dp (Android) causes mis-taps and generates disproportionate accessibility complaints. Apply the minimums to every interactive element, including secondary and icon-only buttons.
- Placing destructive actions in the high-frequency thumb zone. The lower two-thirds of the screen is the easiest reach area. Putting "Delete" or "Log out" near frequently tapped actions causes accidental destructive interactions. Keep destructive actions away from high-frequency zones and require confirmation.
- Requesting permissions on first launch. Users who have not yet experienced the app's value deny permissions at high rates, and iOS/Android only allow one native prompt per permission. Request permissions at a contextually relevant moment after the user has seen the benefit.
- Not testing with the system font at maximum scale. Dynamic Type (iOS) and font scaling (Android) can triple the effective font size. Fixed-height containers, truncated labels, and overflowing text are only visible when tested at the maximum system accessibility font scale.
- Designing for online-only without an offline state. Users regularly use apps in low-signal environments. An app that silently fails or shows blank screens when offline creates broken experiences. Design the offline state explicitly: show cached content, queue writes, and display clear "offline" indicators.
- Making gestures the only way to perform an action. Swipe-to-delete or pull-to-refresh as the sole access method excludes users who cannot perform those gestures. Always pair gestures with a discoverable alternative — a button, long-press menu, or context action.
Full reference
iOS HIG vs Material Design — navigation
| Aspect |
iOS (HIG) |
Android (Material 3) |
| Primary nav |
Bottom tab bar (UITabBarController) |
Bottom navigation bar (NavigationBar) |
| Tab limit |
5 max (more goes to "More" tab) |
3-5 destinations |
| Secondary nav |
Back button (top-left) |
System back gesture/button |
| Drawer |
Rare — prefer tabs or lists |
Common for 5+ destinations |
| Stack |
UINavigationController push/pop |
Fragment/Activity back stack |
| Modals |
Sheet sliding up, swipe to dismiss |
Bottom sheet or dialog |
Typography
| Element |
iOS (SF Pro) |
Android (Roboto / Material Type Scale) |
| Large title |
34pt bold |
Display Large: 57sp |
| Title |
17pt semibold |
Title Large: 22sp |
| Body |
17pt regular |
Body Large: 16sp |
| Caption |
12pt regular |
Body Small: 12sp |
| Line height |
~1.2x font size |
~1.25-1.5x font size |
Both platforms require support for dynamic font sizing — never
hardcode sizes.
Iconography
| Aspect |
iOS |
Android |
| Icon set |
SF Symbols (5000+ icons) |
Material Symbols (3000+ icons) |
| Style |
Outline by default, filled for active tab |
Filled or outlined per Material theme |
| Size |
22-28pt for toolbar/tab icons |
24dp standard |
| Weight |
Matches text weight (dynamic) |
Fixed weight per variant |
Spacing and layout
| Aspect |
iOS |
Android |
| Base grid |
8pt grid (some 4pt) |
8dp / 4dp grid |
| Content margins |
16pt standard, 20pt on larger devices |
16dp standard |
| List row height |
44pt minimum |
48dp minimum (one-line), 56dp (two-line) |
| Card padding |
16pt internal |
16dp internal |
| Safe areas |
Required (notch, home indicator) |
Edge-to-edge with system bar insets |
Color
| Aspect |
iOS |
Android |
| System colors |
Dynamic (adapt to light/dark) |
Material color roles (primary, secondary, surface) |
| Accent color |
App tint color |
Primary color from seed |
| Dark mode |
Elevated surfaces are lighter |
Tonal elevation (surface color shifts) |
| Contrast |
System provides high-contrast variants |
Medium/High contrast themes available |
| Color scheme |
System colors + custom via asset catalog |
Dynamic color from wallpaper (Android 12+) |
Components
| Component |
iOS |
Android |
| Primary button |
Filled or plain text |
Filled button (FilledButton) |
| Secondary button |
Tinted or outline |
Outlined button (OutlinedButton) |
| Toggle |
UISwitch (green/gray) |
Material Switch |
| Date picker |
Wheel or compact popup |
Calendar dialog |
| Alert |
Centered, stacked buttons |
Dialog, side-by-side buttons |
| Action menu |
Action sheet (bottom) |
Bottom sheet or popup menu |
| Search |
Search bar in navigation |
SearchBar widget |
| Pull to refresh |
UIRefreshControl |
SwipeRefreshLayout |
When to follow platform vs cross-platform
Follow platform conventions when:
- The control has a direct platform equivalent (alerts, date
pickers, sheets).
- The gesture is platform-specific (iOS swipe-back, Android system
back).
- Users expect platform-consistent behavior (share sheets,
notifications).
- Accessibility features depend on native patterns (VoiceOver,
TalkBack).
Use cross-platform consistency when:
- The feature is unique to your app (custom visualizations, brand
experience).
- The interaction has no strong platform equivalent.
- Maintaining two designs would create user confusion between
platforms.
- Your brand identity requires visual consistency.
Key principles
- Respect the platform — users spend 99% of their time in other
apps.
- Prioritize usability — a familiar pattern beats a clever
custom solution.
- Test on both platforms — what feels natural on iOS may feel
foreign on Android.
- Use adaptive layouts — design once, adapt to platform
conventions in code.
- Accessibility first — both platforms provide excellent a11y
tools; use them.
Further reading
1---2name: mobile-app-design3description: Mobile app UX — touch targets, navigation, platform conventions, accessibility. Use when designing mobile interfaces, reviewing mobile UX, adapting web designs for mobile, or reconciling iOS and Android conventions.4---56# Mobile App Design78## Intro910Mobile UX is shaped by finger-sized touch targets, one-thumb reach,11platform conventions, and flaky connectivity. Start with the smallest12supported screen, respect platform idioms for navigation and13components, and design for offline-first use from the beginning.1415## Overview1617### Touch target sizing1819- Minimum 44x44 points (iOS) / 48x48 dp (Android) for all20 interactive elements.21- At least 8pt gap between targets to prevent mis-taps.22- Primary CTAs 48-56pt high.23- Thumbs reach the lower two-thirds of the screen easily — put24 frequent actions there.25- Keep destructive actions away from frequent-tap zones.26- Floating action buttons: 56dp standard, 40dp mini.2728### Navigation patterns2930- **Tab bar (bottom):** 3-5 top-level destinations, always visible,31 best for peer sections.32- **Navigation drawer (hamburger):** 5+ destinations or infrequent33 sections.34- **Stack navigation:** push/pop for hierarchical detail screens.35- **Modal sheets:** temporary tasks, filters, confirmations —36 dismiss with swipe or button.3738Keep depth shallow (3 levels max). Show a back button or39swipe-to-go-back gesture on every non-root screen. Persistent bottom40nav should highlight the active tab and not reset tab state on41re-tap.4243### Responsive layouts4445Design for the smallest supported screen first (375pt width for iOS,46360dp for Android). Use a 4pt or 8pt spacing grid. Support landscape47unless the content is strongly portrait-oriented. Adapt to tablets48with split-view or increased content width via max-width constraints.49Support Dynamic Type (iOS) and font scaling (Android) — never50hardcode font sizes — and test with the system font set to its51maximum size to catch overflow.5253### iOS vs Android conventions5455- **Back navigation:** iOS swipe-from-edge or top-left button;56 Android system back button or gesture.57- **Tabs:** iOS bottom tab bar; Android bottom navigation bar or top58 tabs.59- **Buttons:** iOS plain text or rounded rect; Android filled or60 outlined Material buttons.61- **Alerts:** iOS centered alerts with stacked buttons; Android62 dialogs with side-by-side buttons.63- **Typography:** iOS uses SF Pro; Android uses Roboto or system64 font.65- **Icons:** iOS SF Symbols (outline by default); Android Material66 Icons (filled or outlined).6768When in doubt, follow platform conventions — users expect familiar69behavior.7071### Gesture patterns7273- **Tap:** primary interaction — feedback under 100ms.74- **Long press:** secondary actions, context menus — always provide75 a visible alternative.76- **Swipe:** list actions (delete, archive), sheet dismissal, page77 navigation.78- **Pull to refresh:** standard for list content — show a spinner.79- **Pinch to zoom:** images, maps — provide zoom controls as an80 alternative.8182Make swipe actions discoverable with a peek animation on first use.83Never make gestures the only way to perform an action.8485### Accessibility8687Support screen readers with labels on every interactive element and88image. Maintain 4.5:1 text contrast, 3:1 UI contrast. Support Dynamic89Type and font scaling without layout breakage. Provide captions or90transcripts for audio/video. Test with VoiceOver (iOS) and TalkBack91(Android). Ensure touch targets stay accessible at all accessibility92zoom levels. Respect reduced-motion preferences with static93alternatives.9495### Offline-first design9697- Show cached content immediately while fetching updates in the98 background.99- Display clear "offline" indicators — never silently fail.100- Queue user actions when offline and sync when reconnected.101- Use optimistic UI: show the result immediately, reconcile later.102- Store critical data locally — users expect apps to work without103 signal.104- Design conflict resolution for collaborative data.105106### Push notifications107108- Request permission at a contextually relevant moment, not on first109 launch.110- Explain the value before asking ("Get notified when your order111 ships").112- Group related notifications to avoid overwhelming the user.113- Deep link from notifications directly to the relevant content.114- Respect notification settings — provide in-app controls to115 customize.116- Never use notifications for marketing on first install — earn117 trust first.118119### Onboarding flows120121- Keep onboarding to 3-5 screens maximum — users want to use the122 app.123- Show value immediately — let users explore before requiring124 sign-up.125- Progressive disclosure: teach features as users encounter them.126- Skip onboarding for returning users by checking for existing data.127- Provide a "Skip" option on every onboarding screen.128- Prefer contextual tooltips and coach marks over upfront tutorials.129130## Gotchas131132Agent-specific failure modes — provider-neutral pause-and-self-check items:133134- **Designing for the largest screen first and scaling down.** Starting with a wide screen allows fitting too much content, which breaks on the common 375pt iPhone viewport. Design for the smallest supported screen first, then progressively enhance for larger displays.135- **Using touch targets smaller than platform minimums.** Anything below 44×44 points (iOS) or 48×48 dp (Android) causes mis-taps and generates disproportionate accessibility complaints. Apply the minimums to every interactive element, including secondary and icon-only buttons.136- **Placing destructive actions in the high-frequency thumb zone.** The lower two-thirds of the screen is the easiest reach area. Putting "Delete" or "Log out" near frequently tapped actions causes accidental destructive interactions. Keep destructive actions away from high-frequency zones and require confirmation.137- **Requesting permissions on first launch.** Users who have not yet experienced the app's value deny permissions at high rates, and iOS/Android only allow one native prompt per permission. Request permissions at a contextually relevant moment after the user has seen the benefit.138- **Not testing with the system font at maximum scale.** Dynamic Type (iOS) and font scaling (Android) can triple the effective font size. Fixed-height containers, truncated labels, and overflowing text are only visible when tested at the maximum system accessibility font scale.139- **Designing for online-only without an offline state.** Users regularly use apps in low-signal environments. An app that silently fails or shows blank screens when offline creates broken experiences. Design the offline state explicitly: show cached content, queue writes, and display clear "offline" indicators.140- **Making gestures the only way to perform an action.** Swipe-to-delete or pull-to-refresh as the sole access method excludes users who cannot perform those gestures. Always pair gestures with a discoverable alternative — a button, long-press menu, or context action.141142## Full reference143144### iOS HIG vs Material Design — navigation145146| Aspect | iOS (HIG) | Android (Material 3) |147|---|---|---|148| Primary nav | Bottom tab bar (UITabBarController) | Bottom navigation bar (NavigationBar) |149| Tab limit | 5 max (more goes to "More" tab) | 3-5 destinations |150| Secondary nav | Back button (top-left) | System back gesture/button |151| Drawer | Rare — prefer tabs or lists | Common for 5+ destinations |152| Stack | UINavigationController push/pop | Fragment/Activity back stack |153| Modals | Sheet sliding up, swipe to dismiss | Bottom sheet or dialog |154155### Typography156157| Element | iOS (SF Pro) | Android (Roboto / Material Type Scale) |158|---|---|---|159| Large title | 34pt bold | Display Large: 57sp |160| Title | 17pt semibold | Title Large: 22sp |161| Body | 17pt regular | Body Large: 16sp |162| Caption | 12pt regular | Body Small: 12sp |163| Line height | ~1.2x font size | ~1.25-1.5x font size |164165Both platforms require support for dynamic font sizing — never166hardcode sizes.167168### Iconography169170| Aspect | iOS | Android |171|---|---|---|172| Icon set | SF Symbols (5000+ icons) | Material Symbols (3000+ icons) |173| Style | Outline by default, filled for active tab | Filled or outlined per Material theme |174| Size | 22-28pt for toolbar/tab icons | 24dp standard |175| Weight | Matches text weight (dynamic) | Fixed weight per variant |176177### Spacing and layout178179| Aspect | iOS | Android |180|---|---|---|181| Base grid | 8pt grid (some 4pt) | 8dp / 4dp grid |182| Content margins | 16pt standard, 20pt on larger devices | 16dp standard |183| List row height | 44pt minimum | 48dp minimum (one-line), 56dp (two-line) |184| Card padding | 16pt internal | 16dp internal |185| Safe areas | Required (notch, home indicator) | Edge-to-edge with system bar insets |186187### Color188189| Aspect | iOS | Android |190|---|---|---|191| System colors | Dynamic (adapt to light/dark) | Material color roles (primary, secondary, surface) |192| Accent color | App tint color | Primary color from seed |193| Dark mode | Elevated surfaces are lighter | Tonal elevation (surface color shifts) |194| Contrast | System provides high-contrast variants | Medium/High contrast themes available |195| Color scheme | System colors + custom via asset catalog | Dynamic color from wallpaper (Android 12+) |196197### Components198199| Component | iOS | Android |200|---|---|---|201| Primary button | Filled or plain text | Filled button (FilledButton) |202| Secondary button | Tinted or outline | Outlined button (OutlinedButton) |203| Toggle | UISwitch (green/gray) | Material Switch |204| Date picker | Wheel or compact popup | Calendar dialog |205| Alert | Centered, stacked buttons | Dialog, side-by-side buttons |206| Action menu | Action sheet (bottom) | Bottom sheet or popup menu |207| Search | Search bar in navigation | SearchBar widget |208| Pull to refresh | UIRefreshControl | SwipeRefreshLayout |209210### When to follow platform vs cross-platform211212Follow platform conventions when:213214- The control has a direct platform equivalent (alerts, date215 pickers, sheets).216- The gesture is platform-specific (iOS swipe-back, Android system217 back).218- Users expect platform-consistent behavior (share sheets,219 notifications).220- Accessibility features depend on native patterns (VoiceOver,221 TalkBack).222223Use cross-platform consistency when:224225- The feature is unique to your app (custom visualizations, brand226 experience).227- The interaction has no strong platform equivalent.228- Maintaining two designs would create user confusion between229 platforms.230- Your brand identity requires visual consistency.231232### Key principles2332341. **Respect the platform** — users spend 99% of their time in other235 apps.2362. **Prioritize usability** — a familiar pattern beats a clever237 custom solution.2383. **Test on both platforms** — what feels natural on iOS may feel239 foreign on Android.2404. **Use adaptive layouts** — design once, adapt to platform241 conventions in code.2425. **Accessibility first** — both platforms provide excellent a11y243 tools; use them.244245### Further reading246247- `references/platform-guidelines.md` — source for the iOS vs248 Material comparison tables above.249- [Apple Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/)250- [Material Design 3](https://m3.material.io/)