UI-agnostic, language-agnostic. Works for web (CSS/Flex/Grid), Flutter, SwiftUI, Jetpack Compose, React Native, UIKit.
1. Sizing
DO
- Preserve design tokens exact: padding, margin, gap, corner radius, border width. These are intentional.
- Use intrinsic sizing: HUG content →
fit-content/wrap_content/.fixedSize()/MainAxisSize.min. - Use extrinsic sizing: FILL parent →
flex: 1/Expanded/match_parent/.frame(maxWidth: .infinity). - Fix only one axis when needed (e.g. button height 48, width flex). Lets other axis breathe.
- Min/max constraints over fixed:
min-width,max-width,clamp(),BoxConstraints.
DON’T
- No fixed width + fixed height on layout containers. Breaks on locale, font scaling, screen size.
- No pixel-perfect positioning (
left: 24, top: 100) for flow content. Use layout primitives. - No hard line breaks in text. Let text reflow.
- No fixed height on text containers. Content decides height.
2. Spacing & Alignment
DO
- Keep design padding/margin/gap 1:1 with Figma. This is the design language.
- Use gap/spacing tokens from design system (8, 12, 16, 24…), not one-off numbers.
- Semantic alignment:
center,space-between,start,end— match Figma auto-layout alignment exactly. - Logical properties where supported:
padding-inline,margin-block— RTL-safe.
DON’T
- No margin hacks to fake spacing. Use container gap.
- No negative margins to compensate layout bugs.
- No
left/right(directional). Preferstart/endfor i18n.
3. Images & Media — Aspect Ratio MANDATORY
DO
- Always declare aspect ratio:
aspect-ratio: 16/9/AspectRatio(aspectRatio: 16/9)/ContentMode.fit. width: 100%; height: autopattern (or platform equivalent).- Reserve space before load — prevents layout shift (CLS). Set intrinsic dimensions or ratio box.
- Use
object-fit: coverfor hero/thumb (crop OK),containfor logos (no crop). - Serve responsive sources:
srcset/sizeson web, density buckets (@2x,@3x,mdpi/hdpi/xhdpi) on native. - Vector for icons (SVG / VectorDrawable / SF Symbols / AssetImage with svg package).
DON’T
- No fixed
width+ fixedheighton<img>/Imagethat don’t match source ratio → distortion. - No stretch-to-fill without aspect guarantee.
- No giant raster for tiny thumb. Ship sized assets.
4. Responsive vs Adaptive Strategy
DO
- Fluid responsive first, adaptive second (hybrid). Baseline fluid, then breakpoint-level layout swaps only when UX demands it.
- Mobile-first: design smallest, enhance up with
min-widthqueries / size classes. - Content-driven breakpoints: add where layout breaks, not at device widths. Test content, not pixels.
- Container queries where supported (web, Compose
BoxWithConstraints, SwiftUIGeometryReader/size classes). Component responds to parent, not viewport. - Adaptive layout swap for genuinely different UX: hamburger → sidebar, bottom-sheet → dialog, list → grid. Don’t cram desktop UI on phone.
DON’T
- No desktop-first scaled down. Always compromises mobile.
- No arbitrary device breakpoints (
iPhone 14 width). Devices change. - No same component structure across phone + tablet + desktop if UX differs.
5. Typography
DO
- Fluid type:
clamp(min, preferred, max)on web,DynamicType/textScaleFactor/spon native. - Respect system text scale (accessibility) — use
spin Android, Dynamic Type in iOS,MediaQuery.textScalerin Flutter. - Line-height as unitless/ratio (1.4, 1.5) — scales with font.
- Max line length ~60-75ch for readability.
DON’T
- No hardcoded pixel font sizes that ignore user scale.
- No fixed heights on text boxes.
- No
overflow: hiddenon dynamic text without tested max.
6. Layout Primitives (Flex Way)
DO
- Map Figma Auto Layout 1:1 to flex primitive of platform:
- Web:
display: flex+ gap - Flutter:
Row/Column+SizedBox/Gap - SwiftUI:
HStack/VStackwithspacing - Compose:
Row/ColumnwithArrangement.spacedBy - React Native:
flexDirection+gap
- Web:
- Grid for 2D (CSS Grid,
LazyVGrid,GridView). Don’t fake grid with nested flex. - Wrap/flow layouts for chips/tags:
flex-wrap,Wrap(Flutter),FlowRow(Compose). - Spacer / flex spacer for push-apart patterns instead of margin.
DON’T
- No absolute positioning for flow content. Only for overlays (badge, tooltip, FAB).
- No nested
Row(Row(Row(…)))when one grid/wrap fits. - No manual offset math to fake alignment.
7. Units
DO
- Relative units:
rem/em/%/vw/vh(web),dp/sp(Android), points (iOS — density-independent by default), logical pixels (Flutter). - Tokenize scale: spacing/radius/typography from a scale (4/8 base grid).
DON’T
- No
pxfor typography (web). No rawpxfor dimensions on Android (usedp). - No viewport units for critical tap targets (must stay ≥ 44-48 physical px).
8. Components & Tokens
DO
- One component, many states — variants driven by props/slots, not duplicated layouts.
- Design tokens → code tokens 1:1 (colors, spacing, radii, shadows, motion, z-index).
- Semantic tokens (
color.surface.primary) over raw (#FFFFFF). Theming/dark mode free. - Slot-based composition for content-agnostic shells.
DON’T
- No separate mobile/desktop components for same semantic UI if one responsive version works.
- No hex colors inline. Go through token.
- No magic numbers. If it appears twice, tokenize.
9. Touch Targets & Accessibility
DO
- Min tap target 44×44 pt (iOS HIG) / 48dp (Material) regardless of visual size.
- Focus states, contrast ratios, semantic roles preserved from design (or added if design missed).
- Honor motion-reduce / reduce-transparency system prefs.
DON’T
- No 24×24 icon button without padding to 44/48 tap area.
- No color-only state indication.
10. Handoff Workflow
DO
- Read Figma auto-layout intent, not frame width.
Hug/Fill/Fixed→ maps to intrinsic/flex/fixed in code. - Ignore absolute Figma frame sizes for container widths. Those are canvas snapshots.
- Extract tokens first, then layout, then components, then screens.
- Test at 320px, 360px, 390px, 768px, 1024px, 1440px and at 200% browser zoom / largest Dynamic Type.
DON’T
- No copy-paste
width: 1440pxfrom Figma desktop frame. - No pixel-sniffing screenshots to measure. Read auto-layout + tokens.
- No shipping without testing longest-string locale (DE/RU) + RTL (AR/HE) + largest font scale.
Golden Rules (TL;DR)
- Padding, margin, gap, radius = design sacred. Copy exact.
- Width/height = usually not sacred. Prefer Hug/Fill. Fix only one axis, only when needed.
- Images = aspect ratio always. Never fixed w+h both unless ratio matches source.
- Flex first, grid for 2D, absolute only for overlays.
- Mobile-first fluid, breakpoint only where content breaks.
- Tokens over raw values — everywhere.
- Test: small screen, big screen, big font, long text, RTL.
Sources
- Guide to auto layout — Figma
- Integrating Flexbox Principles with Figma Auto Layout — PROS
- Responsive Design in Figma 2026 — thinkdesignblog
- Responsive vs Adaptive Design 2026 — UXPin
- Responsive Web Design Complete Guide 2026 — Scrimba
- Aspect Ratios — MDN
- Setting Height/Width on Images Important Again — Smashing
- img aspect-ratio vs width/height — Jake Archibald
- object-fit tutorial — DigitalOcean
- Design System Mastery with Figma Variables 2025/2026 — Design Systems Collective