Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Reference guide to native UI conventions across iOS (Apple HIG), Android (Material 3), macOS, Windows 11 Fluent, and web — with concrete numbers, comparison tables, and when to adapt vs. when to ship a custom cross-platform brand system.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-10 | ✗→✓ | ▲ Improved | 297% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 382% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 701% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 256% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 365% | 0% |
A platform convention is a contract the OS already taught the user. SF Symbols, the back-swipe, the FAB, the menu bar — these are muscle memory, not decoration. When you honor them your app feels native and invisible; when you fight them you spend the user's attention re-teaching things they already know. This skill is the cross-platform bible: what each platform expects, the exact numbers, and the trade-off of when to break with convention on purpose.
The recurring decision in every section below is the same: inherit the platform's pattern (cheaper, familiar, accessible-by-default) or impose your own (coherent, branded, but you pay to re-teach and re-implement). Read each platform's section as the catalog of what you get for free if you conform, so you know exactly what you're spending when you don't.
Respect them when: the value is in the content/task, not the chrome (productivity, utility, system-adjacent apps); you want App Store / Play Store reviewer goodwill; your users span ability levels (native controls inherit accessibility for free); you're a small team that can't afford to re-solve solved problems.
Use a custom cross-platform brand system when: the brand is the product (games, creative tools, immersive media, strongly-branded consumer apps like Spotify/Notion/Linear); a consistent identity across platforms outweighs per-platform familiarity; you control onboarding enough to teach novel patterns. Spotify, Discord, and Figma deliberately look identical everywhere — that consistency is the point.
The trade-off, stated plainly: Native = lower learning cost, free accessibility, store goodwill, but per-platform engineering and a fragmented brand. Custom = one design language and brand coherence, but you re-implement accessibility, you fight platform reflexes (back gesture, share sheet), and stores scrutinize you harder. The mature answer is almost always hybrid: a shared brand token layer (color, type scale, spacing, motion personality) with platform-native navigation, controls, and gestures. Never ship an iOS app that looks Android, or vice versa — that's the one thing users universally read as "cheap port."
Store reality: Apple's App Store Review Guidelines reject apps that feel like a "repackaged website" or ignore platform paradigms (§4.0 Design); Apple expects you to use system controls, the native share sheet, and standard navigation. Google Play is more permissive on UI but still rejects on broken back behavior, deceptive patterns, and accessibility failures. Conforming isn't only good UX — it materially lowers rejection risk and speeds review.
Type: SF Pro (SF Pro Text < 20pt, SF Pro Display ≥ 20pt; New York is the serif). Dynamic Type is mandatory — use the 11 text styles (LargeTitle 34, Title1 28, Title2 22, Title3 20, Headline 17 semibold, Body 17, Callout 16, Subhead 15, Footnote 13, Caption1 12, Caption2 11). Never hardcode point sizes for body content; users set their own scale (xSmall→AX5), and respecting it is an accessibility requirement, not an option.
Touch & grid: Minimum tap target 44×44 pt (HIG hard floor). Layout on an 8 pt grid (4 pt for fine tuning). Standard screen margin 16–20 pt. Points are density-independent; the system rasterizes @1x/@2x/@3x.
Navigation:
.medium/.large, drag-to-dismiss grabber) over full-screen modals. Use full-screen cover only for self-contained tasks. Action sheets for destructive choices anchored to context.System feel:
safeAreaInsets, never the raw screen rect.UIFeedbackGenerator (selection / impact / notification): expected on toggles, pickers, and success/error moments..ultraThinMaterial→.thickMaterial vibrancy for bars, popovers, sidebars — don't fake translucency with a flat alpha fill..label, .systemBackground, .separator), never hardcoded hex.Standard components — reach for these first: UIDatePicker (wheel/compact/inline), segmented control, stepper, switch (green capsule), context menus (long-press), swipe actions on rows, and the system share sheet (UIActivityViewController) — never roll your own share UI.
iPadOS is its own interaction model, not a big iPhone:
UISplitViewController: sidebar / supplementary / secondary) collapses to a stack on iPhone-width.visionOS basics: content lives on glass material in 3D space; default window 1280×720 pt at 1m; targets ≥60 pt for eye+pinch; hover highlight is system-driven; put tab bars/toolbars in ornaments rather than screen-edge chrome.
iOS do / don't:
17pt; use the Body text style so Dynamic Type and accessibility sizes flow through.Type: Roboto (or Roboto Flex) is the default; brand fonts allowed. Type scale tokens: Display L/M/S, Headline L/M/S, Title L/M/S, Body L/M/S (Body Large 16sp), Label L/M/S. Units are sp for text (scales with user font setting) and dp for everything else. Using dp for text is a bug — it ignores accessibility font scaling.
Dynamic color (Material You): M3's signature — the system extracts a tonal palette from the user's wallpaper and exposes it via color-role tokens (primary, onPrimary, primaryContainer, surface, surfaceContainerHighest, outline…). Design against roles, not raw hex, so your app re-themes itself per device. Provide a static brand fallback for when dynamic color is off.
Touch & grid: Minimum target 48×48 dp (8 dp larger than iOS). 8 dp grid, 4 dp for fine spacing/icon padding. Default screen margins 16 dp.
Navigation:
surfaceContainer color shift.Surfaces & state:
surfaceContainerLow→surfaceContainerHighest) rather than only a shadow.onSurface overlay (8% / 10% / 10% / 16%).Motion durations (M3 tokens): short 50–200 ms (state changes, small components) · medium 250–400 ms (most container transitions) · long 450–600 ms (large/full-screen) · extra-long 700–1000 ms (hero moments). Easing is emphasized (emphasizedDecelerate/emphasizedAccelerate, ~cubic-bezier(0.05,0.7,0.1,1)) with container-transform and shared-axis transitions. For contrast: iOS motion is spring-based (no fixed duration ramp, ~0.3–0.5 s defaults, mass/stiffness/damping); Fluent sits ~150–300 ms.
Android do / don't:
dp — it silently ignores the user's font-scale setting.| Dimension | iOS (HIG) | Android (Material 3) | |---|---|---| | Primary navigation | Tab bar (bottom, 2–5) | Navigation bar (bottom, 3–5) / rail / drawer | | "Back" | Top-left chevron + edge-swipe | System back (gesture / button); no per-screen back needed | | Hamburger menu | Avoid — un-iOS | Acceptable (navigation drawer) | | Primary screen action | Top-right bar button | FAB (bottom-right) | | Modal pattern | Sheet with detents, drag-to-dismiss | Bottom sheet / full-screen dialog | | Alert / transient msg | Alert + action sheet | Dialog + snackbar | | Type unit | pt (Dynamic Type styles) | sp (text) / dp (layout) | | Min touch target | 44 pt | 48 dp | | Grid | 8 pt (4 fine) | 8 dp (4 fine) | | Icon style | SF Symbols — thin, rounded, optically sized | Material Symbols — geometric, fill/weight/grade axes | | Switch | Green capsule, no label inside | Track + thumb with checkmark, role-colored | | Date picker | Wheel / compact / inline calendar | Calendar dialog / docked / dial time picker | | Share | System share sheet (UIActivityViewController) | Android Sharesheet (ACTION_SEND) | | Settings | Inside the app (Settings.app for system perms) | In-app + system Settings deep links | | Color theming | Semantic system colors, vibrancy | Dynamic color from wallpaper (tonal roles) | | Elevation | Materials / blur layering | Tonal elevation + shadow + state layers |
Cardinal sins: an iOS-looking app on Android (and vice versa) reads as a low-effort port. The most damaging are: a top-left back button on Android (use system back), a FAB on iOS, a hamburger drawer on iOS, hardcoded font sizes that ignore Dynamic Type / sp, custom non-native date pickers, and a bespoke share screen instead of the OS share sheet.
Density is the headline difference from iOS — pointer precision means smaller, denser controls (min ~28 pt clickable, not 44), tighter rows, more affordances visible at once. Don't ship an iPad app stretched to a window.
macOS do / don't:
…), context menus, and the right-click menu.Windows do / don't: Do use Mica for the window base, Acrylic for flyouts/menus, rounded corners, and the system accent color. Don't ship flat square-cornered surfaces with hard shadows (reads as legacy Win32), and don't assume mouse-only — Surface devices are touch + pen.
The web has no single OS convention — so you inherit the browser's contract (back/forward, the URL, Ctrl/⌘+F, zoom, reader mode, text selection) and the WCAG baseline, then layer your own design language. Don't break browser back, don't hijack scroll, keep links as links.
The wrapper rule: the moment your web UI is packaged, the host platform's conventions reassert themselves:
env(safe-area-inset-*)), theme-color, the install/standalone display mode, and touch target sizes (≥44 px). On iOS Safari, account for the dynamic toolbar (100dvh not 100vh).Keep consistent (the brand layer): design tokens (color roles, type scale ratios, spacing scale, radius, motion personality), content/voice, information architecture, iconography family, illustration. These travel.
Adapt per platform (the experience layer): navigation structure (tab bar vs. nav bar vs. menu bar), control appearance (switches, pickers, buttons), gestures (back-swipe, long-press vs. right-click), typography units (pt/sp/dp/px) and the system font, share/print/settings hooks, density, and the elevation/material model. These must be native.
Worked example — one "compose new message" feature, five platforms. Same brand color, type ramp, and copy throughout; the behavior is native each time:
File ▸ New Message menu item open a new window; the toolbar holds Send; right-click a recipient for actions.One feature, one brand — five correct platform expressions. That is the whole strategy in miniature.
Framework caveats:
Platform.select, Flutter's Cupertino vs. Material widget sets. "Write once, run anywhere" with one UI = uncanny on at least one platform. Budget for platform-specific navigation and controls.Native controls inherit most of this for free — another reason to conform. If you build custom, you re-implement all of it.
| Platform | Screen reader | Text scaling | Other expected | |---|---|---|---| | iOS / iPadOS | VoiceOver | Dynamic Type (text styles) | Reduce Motion, Increase Contrast, Bold Text, Switch Control, Voice Control; min contrast WCAG AA | | Android | TalkBack | system font scale (use sp) | Switch Access, color-inversion, large-touch, content descriptions on every control | | macOS | VoiceOver | system text size, hover text | Full Keyboard Access, Increase Contrast, Reduce Motion, focus rings | | Windows 11 | Narrator | system text scaling | High Contrast themes, keyboard nav, focus visuals, UI Automation patterns | | Web | platform SR (VoiceOver / NVDA / Narrator) | browser zoom + rem/em | WCAG 2.2 AA, semantic HTML, ARIA only when HTML can't, visible focus, reduced-motion query |
The throughline: every platform exposes a user-chosen text scale and a screen reader. Hardcoded sizes and unlabeled custom controls break both — the single most common accessibility regression across all five.
| Platform | App icon | In-UI icons | Notes | |---|---|---|---| | iOS / iPadOS | 1024×1024 single master (Xcode generates the rest); rounded-rect mask applied by OS — supply a square, no pre-rounded corners | SF Symbols (vector, weight + scale matched to text) | Don't bake the corner radius; provide light/dark/tinted variants (iOS 18) | | Android | Adaptive icon: 108×108 dp = 72 dp safe zone, separate foreground + background layers (system masks to circle/squircle/etc.); Play Store 512×512 | Material Symbols (fill/weight/grade/optical-size axes) | Never a single flat PNG — adaptive layers or it clips wrong | | macOS | 1024×1024, rounded-square with subtle depth (squircle), supply full .icns set | SF Symbols + custom template images | More skeuomorphic depth than iOS flat | | Windows 11 | App icon at multiple sizes (16→256 px) + tile/Store assets; rounded modern style | Fluent / Segoe Fluent Icons | Provide unplated + plated variants | | Web / PWA | favicon set + 512×512 + maskable icon (safe zone for masking) + apple-touch-icon 180×180 | SVG sprite or icon font | Maskable icon prevents Android cropping |
sp (Android).The one rule: ship the brand once, ship the behavior native. Tokens are shared; navigation, controls, and gestures belong to the platform.
Other measured skills in the registry, with their headline benchmark lift.