← All guides

/ mobile_app_design

MOBILE_APP

iOS and Android Are Different Systems, Not One Design Reused Twice

Where HIG and Material genuinely diverge: navigation, back behavior, type defaults, and which components need two designs, not one resized.

INTERMEDIATE · 17 MIN READ · MOBILE APP DESIGN
On this page
  1. The shared-Figma-file trap
  2. Two philosophies of navigation
  3. Back is two systems, not one gesture
  4. Typography is a contract, not a shared scale
  5. Same problem, two different adaptive answers
  6. Sheets, dialogs, and the gesture grammar around them
  7. Touch targets and safe areas aren't interchangeable units
  8. Depth: shadows vs. glass
  9. 2025 reset the gap: Liquid Glass vs. Material 3 Expressive
  10. What can actually share a design
  11. Common mistakes
  12. The spec

01The shared-Figma-file trap

There's a workflow that shows up in almost every team shipping to both platforms at once: design the iOS screen first, duplicate the frame, swap the corner radius from 8 to 4, swap San Francisco for Roboto, nudge a few paddings, and hand the second frame off labeled "Android." It's fast, it's defensible in a sprint review, and it produces two screens that look related. It does not produce two screens that behave like their platforms, because the differences that matter most aren't visual at all — they're in the navigation model, who owns the back gesture, and how the type system is actually built.

For about a decade this trap was easy to fall into and hard to notice, because the visual language of both platforms was genuinely close. iOS 7's 2013 flattening and Material Design's 2014 debut landed within a year of each other and leaned on similar instincts — flat surfaces, card-based content, restrained ornamentation — so a shared visual baseline underneath brand styling felt like a reasonable assumption. That truce ended in 2025. Apple's Liquid Glass, announced at WWDC on June 9, 2025 and shipped that fall across iOS, iPadOS, macOS, watchOS, tvOS, and visionOS, pushed toward a translucent, lensing material borrowed from visionOS's spatial-computing language. Google's Material 3 Expressive, announced at Google I/O on May 13, 2025 and rolled out via the Android 16 QPR1 update that September, pushed the opposite way — bolder color, springier motion, more expressive shape. The two platforms' surfaces are further apart now than at any point since skeuomorphism gave way to flat design.

The visual gap is, honestly, the least important one. It's the easiest thing to notice and the easiest thing to fix with a token swap. The navigation model, the back gesture, and the type contract were already structurally different underneath any color refresh, and none of that gets solved by re-exporting a frame with new corner radii. That's what the rest of this guide is actually about — in the order they'd surface in a real build: navigation, then back behavior, then type, then the individual components that need genuinely separate treatment, then the units underneath all of it.

02Two philosophies of navigation

On the surface, iOS's tab bar and Android's navigation bar now look like they agree. Apple's Human Interface Guidelines recommend three to five tabs on iPhone, used strictly for navigating between top-level, peer sections — never for actions on the current view, which belong in a toolbar instead. Material 3's navigation bar guidance lands on the same range: three to five top-level destinations, each a singular destination, with a different pattern recommended outside that range. If you only compared the counts, you'd conclude the two platforms had converged.

What the shared count hides is a structural split that has nothing to do with how many icons sit in the bar. Android has always drawn a formal line between two navigation concepts that iOS never needed to separate:

  • Up — moves within the app's designed hierarchy. It's always present if the current screen has a logical parent, and it obeys the hierarchy the app defines, not the order the user actually visited screens in.
  • Back — follows the user's actual navigation history. It can retrace through a previous app entirely, and if there's nothing left to retrace, it exits to the home screen.

iOS has no equivalent split. There is exactly one back concept — pop the current view off the navigation stack — and it never leaves the app. Leaving the app is a completely different, unrelated gesture (swiping up from the bottom edge to the App Switcher or Home Screen), assigned to a different part of the system. A screen that has no parent to go "up" to on iOS simply has no back button; there's no second fallback concept waiting behind it.

Android's own default guidance has also shifted, and it's shifted toward iOS's stance rather than away from it. The navigation drawer — the hamburger-triggered side panel that used to be Android's default answer for five or more destinations — is no longer recommended under Material 3 Expressive (2025). Google's current guidance points apps toward the bottom navigation bar on phones and an expanded navigation rail on larger windows instead, because both adapt across breakpoints more gracefully than a drawer does. That's real convergence at the surface level. It just doesn't touch the Up/Back split, which is a platform-level primitive, not a navigation-pattern choice — and it's the piece that breaks silently when a shared component library assumes "back" means the same thing on both sides.

03Back is two systems, not one gesture

This is the single biggest structural gap between the two platforms, and it's almost entirely invisible in a static mockup, because it's not about how the back affordance looks — it's about who owns it.

On iOS, the back affordance is component-owned. It's the leading button of UINavigationBar, automatically labeled with the previous screen's title unless a developer overrides it, and it's paired with a system-provided edge-swipe-from-the-left shortcut that's wired to that exact same pop action. There is no operating-system-level "back" primitive on iOS. If a screen isn't hosted inside a navigation controller, swiping from the left edge does nothing at all, because nothing is listening for it. Leaving the app is a categorically different gesture that has no relationship to any navigation stack.

On Android, back is dispatched by the system to whatever currently owns the screen — an open keyboard, a modal dialog, a bottom sheet, a fragment's own nested back stack, the hosting activity, and, if nothing along that chain intercepts it, all the way out to the home screen. That's a fundamentally different mental model to design against: on Android, every screen state has to answer "what does back do right here," because the same physical gesture routes through all of them. On iOS the question mostly doesn't come up, because navigation-stack pop and app-exit are different gestures with different owners.

iOS · POPS NAV STACK ONLY ANDROID · CAN LEAVE THE APP
iOS's edge-swipe is wired to one navigation controller and stops at the app's own root screen. Android's back gesture is dispatched by the system to whatever's on screen, and keeps going past the app entirely if nothing intercepts it.

The mechanics of that Android gesture have also been changing on a yearly cadence, which matters because a design spec written against last year's behavior can be quietly wrong today:

// predictive back gesture, by Android version
Version What changed
13 (API 33) Introduces a predictive back-to-home preview when exiting an app.
14 (API 34) Adds in-app predictive back — the previous destination previews mid-swipe, and the user can cancel before committing.
15 (API 35) Predictive back's developer-option toggle is removed; enabled by default for apps that have migrated. Edge-to-edge layout is enforced by default for apps targeting this level.
16 (API 36) Remaining opt-outs for predictive-back animations and edge-to-edge enforcement are deprecated for apps targeting this level.

The practical consequence: for every Android screen that holds unsaved state — a half-filled form, an open bottom sheet, a nested flow — the design has to explicitly define what back does at each layer, because the platform fires that event by default whether or not anyone designed for it. An iOS screen with no navigation controller behind it simply never receives an unhandled back event in the first place.

04Typography is a contract, not a shared scale

iOS's type system is eleven named text styles — Large Title, Title 1, Title 2, Title 3, Headline, Body, Callout, Subhead, Footnote, Caption 1, Caption 2 — each with a fixed default point size and line height, all drawn from SF Pro. Every one of those styles scales along Dynamic Type's twelve steps: seven standard sizes from xSmall to xxxLarge, plus five larger accessibility sizes, AX1 through AX5. What changes app to app is which of the eleven named roles gets used where — the letterforms themselves are locked to a single system typeface.

Material 3's type system is organized differently: five roles — display, headline, title, body, label — each in three sizes, large/medium/small, for fifteen tokens total, built on Roboto Flex by default. The meaningful structural difference isn't the token count, though — it's that Material explicitly splits a "brand" typeface (used for display and headline) from a "plain" typeface (used for title, body, and label), making a per-brand typeface swap a supported, first-class customization rather than a workaround. SF Pro has no equivalent split; the system typeface is the typeface, by design.

Lining the two scales up by nearest point size is a useful exercise precisely because it shows why the naive version of this — copy the number, keep the role name — doesn't work:

// approximate crosswalk by size — not an official mapping
iOS text style Size / weight Nearest Material 3 token Size / weight
Large Title 34pt regular Display Small 36sp regular
Title 1 28pt regular Headline Medium 28sp regular
Title 2 22pt regular Title Large 22sp regular
Headline 17pt semibold Title Medium 16sp medium
Body 17pt regular Body Large 16sp regular
Caption 1 12pt regular Body Small / Label Medium 12sp (tie)

Two things fall out of that table that don't fall out of either spec sheet on its own. First, iOS separates Headline from Body almost entirely by weight — both sit at 17pt, and semibold is the only thing distinguishing them — while Material separates its comparable tier partly by size and partly by weight, so a same-named role doesn't land on a same-sized token. Second, at the small end the nearest-size match is a genuine tie between two different Material roles with different jobs (a body token and a label token), which is a sign the two scales weren't built to line up in the first place — they were each built to fit their own platform's density of named roles.

Worth knowing

17pt and 17sp aren't the same physical size, either. Android's sp unit is a density-independent pixel additionally scaled by the user's system font-size preference — so identical numbers don't render identically even before any accessibility scaling is applied on either platform. Treat a hand-off spec as two scales to re-derive role by role, not one set of numbers to transliterate.

05Same problem, two different adaptive answers

Both platforms face an identical problem — a phone-width layout and a tablet-or-larger layout need different navigation chrome, and nobody wants to hand-maintain two designs for it — and both have shipped a built-in, system-sanctioned answer. The answers don't collapse to the same breakpoints or the same shape.

iOS 18 formalized a single TabView that a developer marks .sidebarAdaptable. At compact width — iPhone, or an iPad in a narrower multitasking split — it renders as the familiar bottom tab bar. At regular width — full-screen iPad, Mac Catalyst — the same tab items become a sidebar, and tab groups become section headers. One data structure, two renderings, switched automatically by size class.

Material 3's NavigationSuiteScaffold solves the analogous problem across three window-size-class breakpoints — compact (under 600dp wide), medium (600–839dp), and expanded (840dp and up) — by swapping in a bottom navigation bar, a navigation rail, or a navigation drawer respectively. Material 3 Expressive (2025) changed the top of that ladder: the navigation drawer is being deprecated in favor of an expanded navigation rail even at large widths, because a rail adapts across breakpoints more gracefully than a drawer does. The current recommended shape is closer to bar → rail → wider rail than it is to bar → rail → drawer.

For a cross-platform spec, the useful takeaway isn't to try to force matching breakpoints — Android's rail step has no iOS equivalent below a full sidebar, and the two platforms' terminal states (rail vs. sidebar) aren't the same shape either. Describe the destinations and hierarchy once, then let each platform's own adaptive component do the actual rendering, rather than prescribing pixel-identical behavior at every width.

06Sheets, dialogs, and the gesture grammar around them

iOS sheets — partial- or full-height, with a grabber at the top — dismiss with a discrete swipe-down gesture that's independent of the edge-swipe-back gesture. The two never compete for the same touch input, so a sheet can safely stack on top of a screen that also supports edge-swipe-back without any gesture conflict between them.

Android's bottom sheets, side sheets, and navigation drawers automatically animate with the predictive back gesture once an app has opted in and is running on API 33+. That's good for consistency, but it means the exact same edge-swipe that navigates a screen up a level is also the gesture that dismisses a modal sheet — a sheet's dismiss affordance and the screen's "go back" affordance are the same physical gesture on Android, where they're deliberately different gestures on iOS.

Common misconception

There's a long-repeated claim that iOS orders dialog buttons Cancel-then-OK left-to-right while Android orders them the other way around. Current guidance for both platforms has mostly converged: modern HIG says to place the button people are most likely to choose on the trailing edge — so a destructive "Delete" sits to the right of "Cancel" — and Material's own dialog guidance places the dismissive action directly to the left of the affirmative one, the same left-to-right order. Don't design around a button-order split that mostly isn't there anymore. What still genuinely differs is styling — iOS colors a destructive action's text red; Material routes it through its own error color role — and how tap-outside-to-dismiss defaults behave per dialog type.

07Touch targets and safe areas aren't interchangeable units

iOS's minimum touch target is 44×44 points. Material's is 48×48dp, though WCAG's own Success Criterion 2.5.8 (Level AA) sets a lower absolute floor of 24×24dp, with the stricter Level AAA criterion, 2.5.5, landing at 44×44 — the same number as Apple's baseline, and a lower bar than Material's own recommendation.

A point and a density-independent pixel are not the same physical measurement, and treating them as unit-convertible is a quiet source of drift between platform specs. Android's dp has a published formula: it's anchored to a 160dpi reference density, applied uniformly across a documented set of density buckets, so px = dp × (dpi ÷ 160) everywhere. Apple's point has never had an equivalent public per-inch formula — it's a lookup table Apple maintains per device model, where each device is simply assigned a pixel scale factor (@1x, @2x, @3x), not a value derived from a universal density formula. Don't assume 44pt and 48dp are the same size scaled by a fixed ratio; treat each as its own platform's independently tuned constant, verified against real devices.

Safe areas follow the same pattern of "similar problem, different mechanism." iOS exposes safe-area insets around the home indicator, notch or Dynamic Island, and rounded corners, opted into with viewport-fit=cover and respected with the environment variable:

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
.bottom-bar {
  padding-bottom: max(12px, env(safe-area-inset-bottom));
}

Android's model went from opt-in to enforced: apps targeting Android 15 (API 35) get edge-to-edge layout by default, with content expected to draw behind the system bars and use the platform's window-insets APIs to avoid placing touch targets under the gesture-navigation zones — not just the top and bottom bars, but the left and right edges too, since that's exactly where the back gesture lives. The previous opt-out attribute is deprecated for apps targeting Android 16. A control pinned flush to either screen edge on a modern Android build isn't just a reachability problem the way it would be on iOS — it's sitting directly in a zone the system gesture already claims.

08Depth: shadows vs. glass

Material's elevation model pairs a soft drawn shadow with a tonal surface-color shift — a translucent wash of the primary color layered over the surface, so higher elevation reads as more tinted, not just less flat. That tonal approach exists specifically because a drawn shadow barely registers in dark theme; the color shift keeps elevation legible even where a shadow alone would disappear.

iOS has historically leaned on blur-based materials and vibrancy instead of a drawn-shadow elevation ladder — the frosted-glass tab bar background is the clearest everyday example. Liquid Glass (2025) pushes that further into an explicitly lensing, refractive material that simulates real glass optics — bending and magnifying whatever sits behind it, with a springy deformation on interaction — a genuinely different physical metaphor from Material's flat, tonal surfaces.

The practical consequence: expressing "this card is elevated" with one drawn box-shadow token on both platforms isn't actually matched. On Android that's incomplete without the tonal shift, especially in dark theme; on iOS, a raised surface in current default styling more likely wants a translucent or vibrancy treatment than a shadow at all.

092025 reset the gap: Liquid Glass vs. Material 3 Expressive

Both redesigns landed within a few months of each other and pull in opposite directions. Liquid Glass — announced by Apple's VP of Human Interface Design, Alan Dye, at WWDC on June 9, 2025, and shipped across the "26" generation of Apple's platforms that fall — emphasizes restraint and depth through translucency and refraction, drawing on visionOS's spatial visual language, and deliberately pulls emphasis toward the content underneath the UI chrome rather than the chrome itself.

Material 3 Expressive — announced at Google I/O on May 13, 2025 and rolled out through Android 16 QPR1 that September — leans the opposite way: bolder, more saturated color, springier motion curves, and shape used expressively, with components that morph rather than just resize, aimed at adding emotional warmth and personality rather than restraint.

Neither direction is more correct than the other — they're two different bets about what a mobile interface should feel like in the mid-2020s. What matters for a working designer is narrower: any shared token layer — shadow values, corner radii, translucency levels — that was "close enough" to bridge both platforms during the flat- design decade needs re-examining now, because the assumption of a shared visual baseline underneath brand styling is weaker than it's been in years.

10What can actually share a design

None of this means design two entirely independent apps. Most of the work is genuinely shareable — it's a specific, short list of things that aren't:

Usually fine to share as-is:

  • The information architecture — what the destinations and hierarchy actually are, independent of how each platform renders navigation to them.
  • Copy, content strategy, and voice.
  • Brand color values, as long as they're re-expressed through each platform's own token system rather than hardcoded.
  • Photography, illustration, and icon source assets.
  • The core interaction logic — what happens when someone taps a given control, independent of which gesture triggers it.

Needs two designs, not one resized:

  • Navigation chrome and its adaptive behavior at larger widths — tab bar/sidebar vs. nav bar/rail/drawer.
  • The back/up affordance, and everything that depends on "what does back do here."
  • Sheet and modal dismissal grammar, given how differently the two platforms route that gesture.
  • Elevation and depth treatment.
  • The type scale — re-derived role by role, not transliterated point-for-point.
  • Touch-target and safe-area math.
  • The base visual material itself, wherever a design is following either platform's current default rather than a fully custom system.

11Common mistakes

  • Designing the iOS screen first, then "porting" it to Android by swapping the typeface and rounding the corners, without re-deriving the type scale or the navigation model underneath.
  • Treating 44pt and 48dp as unit-convertible instead of as two independently tuned platform constants.
  • Shipping a custom in-app back button on Android without also wiring it to the system's predictive-back callback, producing two different "back" behaviors half a swipe apart.
  • Placing an interactive control flush against the left or right screen edge on a modern Android build without accounting for the gesture-inset zone the back gesture already claims there.
  • Assuming a tab bar and a navigation bar can share one component with a class swap, when their adaptive behavior at larger widths — sidebar vs. rail or drawer — diverges completely.

12The spec

// platform_defaults.spec

iOS min touch target
44×44pt
Android min touch target
48×48dp (WCAG AA floor: 24×24dp)
iOS tab bar
49pt tall, 3–5 tabs, edge-swipe-back is left only
Android nav bar
~80dp container, 3–5 destinations, back gesture works from either edge
iOS Dynamic Type
11 named text styles across 7 standard + 5 accessibility sizes
Material type scale
15 tokens — 5 roles × 3 sizes
Android back gesture
Predictive preview since API 34; default-on, no dev toggle, since API 35
2025 visual reset
Liquid Glass (iOS 26) vs. Material 3 Expressive (Android 16 QPR1)
Validate on
Real devices, both platforms, default OS gesture navigation enabled

None of these numbers are permanent — Android alone has changed its back-gesture defaults in three of the last four annual releases, and both platforms just reset their visual language in the same year. Treat this spec as a snapshot worth re-checking against the current OS release, not a constant. What doesn't change from release to release is the underlying shape of the problem: iOS's navigation is component-owned and Android's is system-dispatched, and that one structural fact is why a screen "resized" from one platform to the other keeps quietly breaking in the same places.