Mobile UI/UX is the craft of designing interfaces that feel native, fast, and effortless on small, touch-first, handheld screens. Unlike the web, mobile design lives inside two strong ecosystems — Apple's Human Interface Guidelines (HIG) for iOS 18+ and Google's Material Design 3 (M3) for Android — each with its own conventions for navigation, gestures, typography, and motion. Great mobile design respects the platform your user is on while keeping your product recognizably itself.
This guide covers the principles that matter most: platform conventions, touch ergonomics, type and spacing scales, color and contrast, dark mode, layout and safe areas, navigation and gesture patterns, feedback, forms, and accessibility. The goal is to give you a mental checklist you can apply to any screen.
iOS HIG vs Material Design 3
Both design systems solve the same problems — clarity, hierarchy, feedback — but express them differently. iOS leans on translucency, depth, and content-first chrome; Material 3 leans on dynamic color, tonal surfaces (elevation expressed as color, not just shadow), and expressive shape. Building on one platform while ignoring the other's conventions is the most common way an app feels "wrong."
| Concern | iOS (HIG) | Android (Material 3) |
|---|---|---|
| Primary navigation | Tab bar at bottom (up to 5 items) | Navigation bar / bottom bar (3–5 items) |
| Back navigation | Top-left chevron + edge swipe from left | System back gesture (edge swipe) + predictive back |
| Title area | Large title collapsing to inline navigation bar | Top app bar (center or large, collapsing) |
| Primary action | Bar button or prominent button in content | Floating Action Button (FAB) |
| System font | SF Pro (San Francisco) | Roboto / Roboto Flex |
| Switch / control style | Rounded, high-contrast, subtle depth | Tonal surfaces, dynamic color, larger shapes |
| Menus | Context menus (long-press), action sheets | Dropdown/overflow menus, bottom sheets |
Rule of thumb
Use the platform's native components and placement for system-level actions (back, tabs, share, settings). Reserve custom styling for your brand's content, not for reinventing OS-level controls users already know.
Touch Targets & Ergonomics
Fingers are imprecise pointers roughly 8–10mm wide. Both platforms publish minimum tappable sizes so users can hit targets reliably without misfires. Anything smaller than the minimum causes frustration and accessibility failures — always give small icons a larger invisible hit area.
| Guideline | Minimum touch target | Recommended spacing |
|---|---|---|
| iOS (HIG) | 44 × 44 pt | ≥ 8 pt between targets |
| Android (Material 3) | 48 × 48 dp | ≥ 8 dp between targets |
| WCAG 2.2 (AAA) | 44 × 44 CSS px | Adequate offset or spacing |
Design for the thumb zone: on large phones the bottom-center of the screen is easiest to reach, the top corners hardest. Keep primary actions low, put destructive or rare actions out of the natural swipe path, and remember that a "reachable" icon at the top-right is a stretch for one-handed use.
Typography & Spacing Scales
Both platforms ship a semantic type scale so text stays legible and consistent, and so it can scale up for users who increase system font size. Use named text styles (Title, Body, Caption) rather than hardcoded point sizes — this is what lets Dynamic Type and Android font scaling work automatically.
| Role | iOS text style | Material 3 role |
|---|---|---|
| Screen title | Large Title / Title 1 | Headline Large / Display |
| Section header | Title 2 / Title 3 | Title Large / Title Medium |
| Body text | Body | Body Large / Body Medium |
| Secondary / meta | Footnote / Caption | Label / Body Small |
For spacing, use a consistent base unit — an 8pt grid is the de facto standard (with 4pt for fine adjustments). Consistent spacing creates rhythm; arbitrary values make a layout feel noisy. Keep body line length comfortable and give tappable rows generous vertical padding.
Color & Contrast
Color must carry meaning and pass contrast. Aim for WCAG AA: a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text (≥ 18pt or 14pt bold) and for meaningful UI components/icons. Never rely on color alone to convey state — pair it with an icon, label, or shape so color-blind users aren't excluded.
Material 3 introduces dynamic color, deriving a full tonal palette from a seed (often the user's wallpaper). iOS emphasizes semantic system colors (label, systemBackground) that adapt automatically to light/dark and accessibility settings. Prefer these semantic tokens over raw hex values.
Test in the sun
Mobile screens are used outdoors at low brightness. Low-contrast gray-on-gray text that looks elegant in a dark studio becomes unreadable in daylight. Check contrast at reduced brightness, not just on your desk.
Dark Mode
Dark mode is an expectation, not a bonus. Do not simply invert colors. Use dark, desaturated surfaces (avoid pure #000000 for large areas — a dark gray reduces halation and smearing on OLED), and soften bright accent colors so they don't vibrate against dark backgrounds. In Material 3, higher elevation is shown by lighter tonal surfaces rather than heavy shadows. Always define both light and dark values for every semantic token, and test images and illustrations in both.
Layout, Safe Areas & Notches
Modern phones have rounded corners, notches, Dynamic Islands, punch-hole cameras, and home indicators. Content must respect the safe area so nothing important is clipped or hidden behind system UI. Let backgrounds and images extend edge-to-edge, but keep interactive controls and text inside the safe insets.
// SwiftUI — background ignores safe area, content respects it
ZStack {
Color.accentColor.ignoresSafeArea()
VStack { /* controls stay inside safe insets */ }
.padding()
}
// Jetpack Compose — apply system bar insets
Column(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.safeDrawing)
) { /* content */ }
Design responsively for a range of screen sizes and both orientations, plus foldables and tablets. Use adaptive layouts (multi-column on wide screens, single-column on phones) rather than fixed pixel positions.
Navigation Patterns
Pick the right container for your information structure. Mixing patterns arbitrarily disorients users; the pattern should match the mental model of the content.
| Pattern | Use when | Watch out for |
|---|---|---|
| Tab bar | 3–5 peer top-level sections | Too many tabs; unrelated items |
| Stack / push | Drill-down hierarchies (list → detail) | Deep stacks; broken back gesture |
| Drawer / nav rail | Many destinations; secondary items | Low discoverability (hidden) |
| Modal / sheet | Focused, self-contained tasks | Trapping users; nested modals |
Always provide a clear way out of a modal, preserve scroll position when returning to a list, and never break the platform back gesture — on Android, support predictive back so users see a preview of where they're going.
Gestures
Gestures make interfaces fast but are invisible, so treat them as accelerators, not the only path. Support tap, long-press (context menu), swipe (list actions, dismiss), pull-to-refresh, and pinch/zoom where relevant — but never hide a critical action behind a gesture with no visible affordance. Respect system-reserved gestures (edge swipes for back/home) and don't fight them.
Feedback: Haptics, Loading & Skeletons
Every user action should produce immediate, perceptible feedback. Use haptics sparingly and meaningfully (success confirmation, selection change) — overuse desensitizes. For latency, show progress: use skeleton screens for content that will fill in known layouts, spinners for short indeterminate waits, and progress bars for measurable operations. Optimistic UI (updating instantly, reconciling later) makes apps feel dramatically faster.
Empty, loading, error
Design all three states for every data-driven screen. A blank screen with no explanation is the number-one cause of "is it broken?" — give empty states guidance and errors a retry.
Forms & Input UX
Forms are where users abandon. Reduce friction: request the correct keyboard type per field (email, number, phone), enable autofill and one-time-code suggestions, validate inline with helpful messages (not just red borders), and keep the submit button visible above the keyboard. Group related fields, minimize required fields, and never make the user re-enter data the OS can provide.
Accessibility
Accessibility is a baseline, not an add-on. Screen readers — VoiceOver on iOS and TalkBack on Android — read your UI aloud, so every meaningful control needs a clear semantic label and every decorative image should be hidden from the reader. Support Dynamic Type / font scaling, honor Reduce Motion, and ensure a logical focus order.
// SwiftUI — VoiceOver label + trait
Button(action: addItem) {
Image(systemName: "plus")
}
.accessibilityLabel("Add item")
.accessibilityHint("Creates a new list entry")
// Jetpack Compose — TalkBack content description
IconButton(onClick = { addItem() }) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "Add item"
)
}
Test with the screen reader on, with the largest font size, and with a color-contrast checker. If your app is usable eyes-closed and in bright sunlight at 200% text size, it's usable for far more people than just those with disabilities.
Microcopy & Performance Perception
Words are UI. Buttons should say what they do (Save changes, not OK), errors should tell the user how to recover, and tone should stay calm and human. Perceived performance often matters more than raw speed: instant tap feedback, skeletons, and pre-fetching make a technically-slower app feel faster than a snappy one that shows blank frames.
Do & Don't
| Do | Don't |
|---|---|
| Use native components and placement | Reinvent OS-level controls |
| Meet 44pt / 48dp touch targets | Ship tiny, crowded tap areas |
| Design empty, loading, and error states | Show blank screens with no feedback |
| Convey state with color + icon/label | Rely on color alone |
| Support Dynamic Type & screen readers | Hardcode font sizes; skip labels |
Practice Exercises
- Take a screen from an app you use daily and audit every tappable element against the 44pt / 48dp minimum. List the failures and how you'd fix them.
- Redesign a single form (e.g. a sign-up screen) to minimize friction: correct keyboard types, autofill, inline validation, and a keyboard-safe submit button.
- Build both light and dark versions of one screen using only semantic color tokens. Verify every text/background pair meets WCAG AA contrast.
- Turn on VoiceOver (iOS) or TalkBack (Android) and navigate a screen you designed eyes-closed. Note every control that is unlabeled or read in a confusing order.
- Add empty, loading (skeleton), and error states to a data-driven list screen, with helpful microcopy and a retry action for the error case.
- Compare the same feature's navigation on iOS and Android and propose a design that respects each platform's conventions (tab bar vs nav bar, back gesture, FAB vs bar button).