Mobile UI Optimization
Quick Reference
Viewport Setup
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
Safe Areas (iPhone Dynamic Island & Notch)
:root { --safe-area-top: env(safe-area-inset-top); --safe-area-bottom: env(safe-area-inset-bottom); --safe-area-left: env(safe-area-inset-left); --safe-area-right: env(safe-area-inset-right); }
body { padding-top: var(--safe-area-top); padding-bottom: var(--safe-area-bottom); padding-left: var(--safe-area-left); padding-right: var(--safe-area-right); }
Touch Target Minimums
-
Minimum size: 44×44px (Apple HIG) / 48×48dp (Material Design)
-
Recommended: 48×48px with 8px spacing between targets
-
Critical actions: 56×56px minimum
Typography Scale
:root { --text-xs: clamp(0.75rem, 2.5vw, 0.875rem); /* 12-14px / --text-sm: clamp(0.875rem, 3vw, 1rem); / 14-16px / --text-base: clamp(1rem, 3.5vw, 1.125rem); / 16-18px / --text-lg: clamp(1.125rem, 4vw, 1.25rem); / 18-20px / --text-xl: clamp(1.25rem, 4.5vw, 1.5rem); / 20-24px / --text-2xl: clamp(1.5rem, 5vw, 2rem); / 24-32px */ }
Device Breakpoints
Device Width Pixel Ratio
iPhone SE 375px 2x
iPhone 14/15/16 390px 3x
iPhone 14/15/16 Pro 393px 3x
iPhone 14/15/16 Plus 428px 3x
iPhone 14/15/16 Pro Max 430px 3x
iPhone 17/18 Pro (expected) 393-402px 3x
Tailwind Breakpoints
// tailwind.config.js screens: { 'xs': '375px', // iPhone SE, small phones 'sm': '390px', // iPhone 14/15/16 base 'md': '430px', // iPhone Pro Max, large phones 'lg': '768px', // Tablets 'xl': '1024px', // Desktop }
Core Patterns
- Responsive Container
<div className="w-full max-w-screen-sm mx-auto px-4 pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)]"> {children} </div>
- Bottom Navigation (iOS Home Indicator Safe)
<nav className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 pb-[env(safe-area-inset-bottom)]"> <div className="flex justify-around py-2"> {/* Nav items with min-h-[44px] */} </div> </nav>
- Touch-Optimized Button
<button className="min-h-[44px] min-w-[44px] px-4 py-3 active:scale-95 transition-transform touch-manipulation"> {label} </button>
- Scroll Container (Momentum Scrolling)
<div className="overflow-y-auto overscroll-contain -webkit-overflow-scrolling: touch scroll-snap-type-y-mandatory"> {children} </div>
Critical Rules
-
NEVER use user-scalable=no or maximum-scale=1
-
breaks accessibility
-
ALWAYS use touch-manipulation on interactive elements to remove 300ms delay
-
ALWAYS account for Dynamic Island/notch with env(safe-area-inset-*)
-
NEVER rely on hover states for critical interactions
-
ALWAYS provide visible focus states for keyboard/assistive technology users
Detailed Guides
-
Viewport & Safe Areas: See VIEWPORT.md
-
Touch Interactions: See TOUCH.md
-
Typography & Readability: See TYPOGRAPHY.md
-
Performance: See PERFORMANCE.md
-
Forms & Inputs: See FORMS.md
-
Navigation Patterns: See NAVIGATION.md
-
Testing Checklist: See TESTING.md